diff --git a/src/main/java/com/loohp/limbo/Console.java b/src/main/java/com/loohp/limbo/Console.java index c54022f..e7ca653 100644 --- a/src/main/java/com/loohp/limbo/Console.java +++ b/src/main/java/com/loohp/limbo/Console.java @@ -1,193 +1,34 @@ package com.loohp.limbo; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PrintStream; -import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Map.Entry; -import java.util.UUID; -import java.util.stream.Collectors; - -import org.fusesource.jansi.Ansi; -import org.fusesource.jansi.Ansi.Attribute; -import org.jline.reader.Candidate; -import org.jline.reader.Completer; -import org.jline.reader.EndOfFileException; -import org.jline.reader.LineReader; -import org.jline.reader.LineReader.SuggestionType; -import org.jline.reader.LineReaderBuilder; -import org.jline.reader.ParsedLine; -import org.jline.reader.UserInterruptException; -import org.jline.terminal.Terminal; -import org.jline.terminal.TerminalBuilder; - import com.loohp.limbo.commands.CommandSender; import com.loohp.limbo.consolegui.ConsoleTextOutput; import com.loohp.limbo.utils.CustomStringUtils; - import jline.console.ConsoleReader; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.BaseComponent; +import org.fusesource.jansi.Ansi; +import org.fusesource.jansi.Ansi.Attribute; +import org.jline.reader.*; +import org.jline.reader.LineReader.SuggestionType; +import org.jline.terminal.Terminal; +import org.jline.terminal.TerminalBuilder; + +import java.io.*; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.Map.Entry; +import java.util.stream.Collectors; public class Console implements CommandSender { - - protected static final Map REPLACEMENTS = new HashMap<>(); - private final static String CONSOLE = "CONSOLE"; - private final static String PROMPT = "> "; - protected final static String ERROR_RED = "\u001B[31;1m"; - protected final static String RESET_COLOR = "\u001B[0m"; - - private Terminal terminal; - private LineReader tabReader; - private ConsoleReader reader; - - private InputStream in; - @SuppressWarnings("unused") - private PrintStream out; - @SuppressWarnings("unused") - private PrintStream err; - protected PrintStream logs; - - public Console(InputStream in, PrintStream out, PrintStream err) throws IOException { - String fileName = new SimpleDateFormat("yyyy'-'MM'-'dd'_'HH'-'mm'-'ss'_'zzz'.log'").format(new Date()); - File dir = new File("logs"); - dir.mkdirs(); - File logs = new File(dir, fileName); - this.logs = new PrintStream(logs); - - if (in != null) { - System.setIn(in); - this.in = System.in; - } else { - this.in = null; - } - System.setOut(new ConsoleOutputStream(this, out == null ? new PrintStream(new OutputStream() { - @Override - public void write(int b) { - //DO NOTHING - } - }) : out, this.logs)); - this.out = System.out; - - System.setErr(new ConsoleErrorStream(this, err == null ? new PrintStream(new OutputStream() { - @Override - public void write(int b) { - //DO NOTHING - } - }) : err, this.logs)); - this.err = System.err; - - reader = new ConsoleReader(in, out); - reader.setExpandEvents(false); - reader.setHandleUserInterrupt(false); - - terminal = TerminalBuilder.builder().streams(in, out).system(true).jansi(true).build(); - tabReader = LineReaderBuilder.builder().terminal(terminal).completer(new Completer() { - @Override - public void complete(LineReader reader, ParsedLine line, List candidates) { - String[] args = CustomStringUtils.splitStringToArgs(line.line()); - List tab = Limbo.getInstance().getPluginManager().getTabOptions(Limbo.getInstance().getConsole(), args); - for (String each : tab) { - candidates.add(new Candidate(each)); - } - } - }).build(); - tabReader.setAutosuggestion(SuggestionType.NONE); - } - - @Override - public String getName() { - return CONSOLE; - } - - @Override - public boolean hasPermission(String permission) { - return Limbo.getInstance().getPermissionsManager().hasPermission(this, permission); - } - - @Override - public void sendMessage(BaseComponent component, UUID uuid) { - sendMessage(component); - } - - @Override - public void sendMessage(BaseComponent[] component, UUID uuid) { - sendMessage(component); - } - - @Override - public void sendMessage(String message, UUID uuid) { - sendMessage(message); - } - @Override - public void sendMessage(BaseComponent component) { - sendMessage(new BaseComponent[] {component}); - } - - @Override - public void sendMessage(BaseComponent[] component) { - sendMessage(String.join("", Arrays.asList(component).stream().map(each -> each.toLegacyText()).collect(Collectors.toList()))); - } - - @Override - public void sendMessage(String message) { - stashLine(); - String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); - ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + message), true); - logs.println(ChatColor.stripColor("[" + date + " Info] " + message)); - try { - reader.getOutput().append("[" + date + " Info] " + translateToConsole(message) + "\n"); - reader.getOutput().flush(); - } catch (IOException e) { - e.printStackTrace(); - } - unstashLine(); - } - - protected void run() { - if (in == null) { - return; - } - while (true) { - try { - String command = tabReader.readLine(PROMPT).trim(); - if (command.length() > 0) { - String[] input = CustomStringUtils.splitStringToArgs(command); - new Thread(() -> Limbo.getInstance().dispatchCommand(this, input)).start(); - } - } catch (UserInterruptException e) { - System.exit(0); - } catch (EndOfFileException e) { - break; - } - } - } - - protected void stashLine() { - try { - tabReader.callWidget(LineReader.CLEAR); - } catch (Exception ignore) {} - } + protected static final Map REPLACEMENTS = new HashMap<>(); + protected final static String ERROR_RED = "\u001B[31;1m"; + protected final static String RESET_COLOR = "\u001B[0m"; + private final static String CONSOLE = "CONSOLE"; + private final static String PROMPT = "> "; - protected void unstashLine() { - try { - tabReader.callWidget(LineReader.REDRAW_LINE); - tabReader.callWidget(LineReader.REDISPLAY); - tabReader.getTerminal().writer().flush(); - } catch (Exception ignore) {} - } - - static { - REPLACEMENTS.put(ChatColor.BLACK, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLACK).boldOff().toString()); + static { + REPLACEMENTS.put(ChatColor.BLACK, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLACK).boldOff().toString()); REPLACEMENTS.put(ChatColor.DARK_BLUE, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLUE).boldOff().toString()); REPLACEMENTS.put(ChatColor.DARK_GREEN, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.GREEN).boldOff().toString()); REPLACEMENTS.put(ChatColor.DARK_AQUA, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.CYAN).boldOff().toString()); @@ -209,286 +50,428 @@ public class Console implements CommandSender { REPLACEMENTS.put(ChatColor.UNDERLINE, Ansi.ansi().a(Attribute.UNDERLINE).toString()); REPLACEMENTS.put(ChatColor.ITALIC, Ansi.ansi().a(Attribute.ITALIC).toString()); REPLACEMENTS.put(ChatColor.RESET, Ansi.ansi().a(Attribute.RESET).toString()); - } - - protected static String translateToConsole(String str) { - for (Entry entry : REPLACEMENTS.entrySet()) { - str = str.replace(entry.getKey().toString(), entry.getValue()); - } - str = str.replaceAll("(?i)" + ChatColor.COLOR_CHAR + "x(" + ChatColor.COLOR_CHAR + "[0-9a-f]){6}", ""); - return str + RESET_COLOR; - } - - public static class ConsoleOutputStream extends PrintStream { - - private PrintStream logs; - private Console console; - - public ConsoleOutputStream(Console console, OutputStream out, PrintStream logs) { - super(out); - this.logs = logs; - this.console = console; - } + } - @SuppressWarnings("resource") - @Override - public PrintStream printf(Locale l, String format, Object... args) { - console.stashLine(); - String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); - ConsoleTextOutput.appendText(ChatColor.stripColor(String.format(l, "[" + date + " Info]" + format, args))); - logs.printf(l, ChatColor.stripColor("[" + date + " Info]" + format), args); - PrintStream stream = super.printf(l, Console.translateToConsole("[" + date + " Info]" + format), args); - console.unstashLine(); - return stream; - } + protected PrintStream logs; + private final Terminal terminal; + private final LineReader tabReader; + private final ConsoleReader reader; + private final InputStream in; + @SuppressWarnings("unused") + private final PrintStream out; + @SuppressWarnings("unused") + private final PrintStream err; - @SuppressWarnings("resource") - @Override - public PrintStream printf(String format, Object... args) { - console.stashLine(); - String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); - ConsoleTextOutput.appendText(ChatColor.stripColor(String.format("[" + date + " Info]" + format, args))); - logs.printf(ChatColor.stripColor("[" + date + " Info]" + format), args); - PrintStream stream = super.printf(ChatColor.stripColor("[" + date + " Info]" + format), args); - console.unstashLine(); - return stream; - } + public Console(InputStream in, PrintStream out, PrintStream err) throws IOException { + String fileName = new SimpleDateFormat("yyyy'-'MM'-'dd'_'HH'-'mm'-'ss'_'zzz'.log'").format(new Date()); + File dir = new File("logs"); + dir.mkdirs(); + File logs = new File(dir, fileName); + this.logs = new PrintStream(logs); - @Override - public void println() { - console.stashLine(); - String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); - ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info]"), true); - logs.println(ChatColor.stripColor("[" + date + " Info]")); - super.println(ChatColor.stripColor("[" + date + " Info]")); - console.unstashLine(); - } + if (in != null) { + System.setIn(in); + this.in = System.in; + } else { + this.in = null; + } + System.setOut(new ConsoleOutputStream(this, out == null ? new PrintStream(new OutputStream() { + @Override + public void write(int b) { + //DO NOTHING + } + }) : out, this.logs)); + this.out = System.out; - @Override - public void println(boolean x) { - console.stashLine(); - String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); - ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + x), true); - logs.println(ChatColor.stripColor("[" + date + " Info]" + x)); - super.println(ChatColor.stripColor("[" + date + " Info]" + x)); - console.unstashLine(); - } + System.setErr(new ConsoleErrorStream(this, err == null ? new PrintStream(new OutputStream() { + @Override + public void write(int b) { + //DO NOTHING + } + }) : err, this.logs)); + this.err = System.err; - @Override - public void println(char x) { - console.stashLine(); - String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); - ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + x), true); - logs.println(ChatColor.stripColor("[" + date + " Info]" + x)); - super.println(ChatColor.stripColor("[" + date + " Info]" + x)); - console.unstashLine(); - } + reader = new ConsoleReader(in, out); + reader.setExpandEvents(false); + reader.setHandleUserInterrupt(false); - @Override - public void println(char[] x) { - console.stashLine(); - String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); - ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + String.valueOf(x)), true); - logs.println(ChatColor.stripColor("[" + date + " Info]" + String.valueOf(x))); - super.println(ChatColor.stripColor("[" + date + " Info]" + String.valueOf(x))); - console.unstashLine(); - } + terminal = TerminalBuilder.builder().streams(in, out).system(true).jansi(true).build(); + tabReader = LineReaderBuilder.builder().terminal(terminal).completer(new Completer() { + @Override + public void complete(LineReader reader, ParsedLine line, List candidates) { + String[] args = CustomStringUtils.splitStringToArgs(line.line()); + List tab = Limbo.getInstance().getPluginManager().getTabOptions(Limbo.getInstance().getConsole(), args); + for (String each : tab) { + candidates.add(new Candidate(each)); + } + } + }).build(); + tabReader.setAutosuggestion(SuggestionType.NONE); + } - @Override - public void println(double x) { - console.stashLine(); - String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); - ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + x), true); - logs.println(ChatColor.stripColor("[" + date + " Info]" + x)); - super.println(ChatColor.stripColor("[" + date + " Info]" + x)); - console.unstashLine(); - } + protected static String translateToConsole(String str) { + for (Entry entry : REPLACEMENTS.entrySet()) { + str = str.replace(entry.getKey().toString(), entry.getValue()); + } + str = str.replaceAll("(?i)" + ChatColor.COLOR_CHAR + "x(" + ChatColor.COLOR_CHAR + "[0-9a-f]){6}", ""); + return str + RESET_COLOR; + } - @Override - public void println(float x) { - console.stashLine(); - String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); - ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + x), true); - logs.println(ChatColor.stripColor("[" + date + " Info]" + x)); - super.println(ChatColor.stripColor("[" + date + " Info]" + x)); - console.unstashLine(); - } + @Override + public String getName() { + return CONSOLE; + } - @Override - public void println(int x) { - console.stashLine(); - String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); - ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + x), true); - logs.println(ChatColor.stripColor("[" + date + " Info]" + x)); - super.println(ChatColor.stripColor("[" + date + " Info]" + x)); - console.unstashLine(); - } + @Override + public boolean hasPermission(String permission) { + return Limbo.getInstance().getPermissionsManager().hasPermission(this, permission); + } - @Override - public void println(long x) { - console.stashLine(); - String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); - ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + x), true); - logs.println(ChatColor.stripColor("[" + date + " Info]" + x)); - super.println(ChatColor.stripColor("[" + date + " Info]" + x)); - console.unstashLine(); - } + @Override + public void sendMessage(BaseComponent component, UUID uuid) { + sendMessage(component); + } - @Override - public void println(Object x) { - console.stashLine(); - String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); - ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + x), true); - logs.println(ChatColor.stripColor("[" + date + " Info]" + x)); - super.println(ChatColor.stripColor("[" + date + " Info]" + x)); - console.unstashLine(); - } + @Override + public void sendMessage(BaseComponent[] component, UUID uuid) { + sendMessage(component); + } - @Override - public void println(String string) { - console.stashLine(); - String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); - ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + string), true); - logs.println(ChatColor.stripColor("[" + date + " Info] " + string)); - super.println(ChatColor.stripColor("[" + date + " Info] " + string)); - console.unstashLine(); - } - } - - public static class ConsoleErrorStream extends PrintStream { - - private PrintStream logs; - private Console console; - - public ConsoleErrorStream(Console console, OutputStream out, PrintStream logs) { - super(out); - this.logs = logs; - this.console = console; - } + @Override + public void sendMessage(String message, UUID uuid) { + sendMessage(message); + } - @SuppressWarnings("resource") - @Override - public PrintStream printf(Locale l, String format, Object... args) { - console.stashLine(); - String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); - ConsoleTextOutput.appendText(ChatColor.stripColor(String.format(l, "[" + date + " Error]" + format, args))); - logs.printf(l, ChatColor.stripColor("[" + date + " Error]" + format), args); - PrintStream stream = super.printf(l, ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + format + RESET_COLOR), args); - console.unstashLine(); - return stream; - } + @Override + public void sendMessage(BaseComponent component) { + sendMessage(new BaseComponent[]{component}); + } - @SuppressWarnings("resource") - @Override - public PrintStream printf(String format, Object... args) { - console.stashLine(); - String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); - ConsoleTextOutput.appendText(ChatColor.stripColor(String.format("[" + date + " Error]" + format, args))); - logs.printf(ChatColor.stripColor("[" + date + " Error]" + format), args); - PrintStream stream = super.printf(ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + format + RESET_COLOR), args); - console.unstashLine(); - return stream; - } + @Override + public void sendMessage(BaseComponent[] component) { + sendMessage(String.join("", Arrays.asList(component).stream().map(each -> each.toLegacyText()).collect(Collectors.toList()))); + } - @Override - public void println() { - console.stashLine(); - String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); - ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error]"), true); - logs.println(ChatColor.stripColor("[" + date + " Error]")); - super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]") + RESET_COLOR); - console.unstashLine(); - } + @Override + public void sendMessage(String message) { + stashLine(); + String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); + ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + message), true); + logs.println(ChatColor.stripColor("[" + date + " Info] " + message)); + try { + reader.getOutput().append("[" + date + " Info] " + translateToConsole(message) + "\n"); + reader.getOutput().flush(); + } catch (IOException e) { + e.printStackTrace(); + } + unstashLine(); + } - @Override - public void println(boolean x) { - console.stashLine(); - String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); - ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + x), true); - logs.println(ChatColor.stripColor("[" + date + " Error]" + x)); - super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + x) + RESET_COLOR); - console.unstashLine(); - } + protected void run() { + if (in == null) { + return; + } + while (true) { + try { + String command = tabReader.readLine(PROMPT).trim(); + if (command.length() > 0) { + String[] input = CustomStringUtils.splitStringToArgs(command); + new Thread(() -> Limbo.getInstance().dispatchCommand(this, input)).start(); + } + } catch (UserInterruptException e) { + System.exit(0); + } catch (EndOfFileException e) { + break; + } + } + } - @Override - public void println(char x) { - console.stashLine(); - String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); - ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + x), true); - logs.println(ChatColor.stripColor("[" + date + " Error]" + x)); - super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + x) + RESET_COLOR); - console.unstashLine(); - } + protected void stashLine() { + try { + tabReader.callWidget(LineReader.CLEAR); + } catch (Exception ignore) { + } + } - @Override - public void println(char[] x) { - console.stashLine(); - String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); - ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + String.valueOf(x)), true); - logs.println(ChatColor.stripColor("[" + date + " Error]" + String.valueOf(x))); - super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + String.valueOf(x)) + RESET_COLOR); - console.unstashLine(); - } + protected void unstashLine() { + try { + tabReader.callWidget(LineReader.REDRAW_LINE); + tabReader.callWidget(LineReader.REDISPLAY); + tabReader.getTerminal().writer().flush(); + } catch (Exception ignore) { + } + } - @Override - public void println(double x) { - console.stashLine(); - String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); - ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + x), true); - logs.println(ChatColor.stripColor("[" + date + " Error]" + x)); - super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + x) + RESET_COLOR); - console.unstashLine(); - } + public static class ConsoleOutputStream extends PrintStream { - @Override - public void println(float x) { - console.stashLine(); - String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); - ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + x), true); - logs.println(ChatColor.stripColor("[" + date + " Error]" + x)); - super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + x) + RESET_COLOR); - console.unstashLine(); - } + private final PrintStream logs; + private final Console console; - @Override - public void println(int x) { - console.stashLine(); - String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); - ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + x), true); - logs.println(ChatColor.stripColor("[" + date + " Error]" + x)); - super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + x) + RESET_COLOR); - console.unstashLine(); - } + public ConsoleOutputStream(Console console, OutputStream out, PrintStream logs) { + super(out); + this.logs = logs; + this.console = console; + } - @Override - public void println(long x) { - console.stashLine(); - String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); - ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + x), true); - logs.println(ChatColor.stripColor("[" + date + " Error]" + x)); - super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + x) + RESET_COLOR); - console.unstashLine(); - } + @SuppressWarnings("resource") + @Override + public PrintStream printf(Locale l, String format, Object... args) { + console.stashLine(); + String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); + ConsoleTextOutput.appendText(ChatColor.stripColor(String.format(l, "[" + date + " Info]" + format, args))); + logs.printf(l, ChatColor.stripColor("[" + date + " Info]" + format), args); + PrintStream stream = super.printf(l, Console.translateToConsole("[" + date + " Info]" + format), args); + console.unstashLine(); + return stream; + } - @Override - public void println(Object x) { - console.stashLine(); - String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); - ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + x), true); - logs.println(ChatColor.stripColor("[" + date + " Error]" + x)); - super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + x) + RESET_COLOR); - console.unstashLine(); - } + @SuppressWarnings("resource") + @Override + public PrintStream printf(String format, Object... args) { + console.stashLine(); + String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); + ConsoleTextOutput.appendText(ChatColor.stripColor(String.format("[" + date + " Info]" + format, args))); + logs.printf(ChatColor.stripColor("[" + date + " Info]" + format), args); + PrintStream stream = super.printf(ChatColor.stripColor("[" + date + " Info]" + format), args); + console.unstashLine(); + return stream; + } - @Override - public void println(String string) { - console.stashLine(); - String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); - ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + string), true); - logs.println(ChatColor.stripColor("[" + date + " Error] " + string)); - super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error] " + string) + RESET_COLOR); - console.unstashLine(); - } - } + @Override + public void println() { + console.stashLine(); + String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); + ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info]"), true); + logs.println(ChatColor.stripColor("[" + date + " Info]")); + super.println(ChatColor.stripColor("[" + date + " Info]")); + console.unstashLine(); + } + + @Override + public void println(boolean x) { + console.stashLine(); + String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); + ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + x), true); + logs.println(ChatColor.stripColor("[" + date + " Info]" + x)); + super.println(ChatColor.stripColor("[" + date + " Info]" + x)); + console.unstashLine(); + } + + @Override + public void println(char x) { + console.stashLine(); + String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); + ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + x), true); + logs.println(ChatColor.stripColor("[" + date + " Info]" + x)); + super.println(ChatColor.stripColor("[" + date + " Info]" + x)); + console.unstashLine(); + } + + @Override + public void println(char[] x) { + console.stashLine(); + String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); + ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + String.valueOf(x)), true); + logs.println(ChatColor.stripColor("[" + date + " Info]" + String.valueOf(x))); + super.println(ChatColor.stripColor("[" + date + " Info]" + String.valueOf(x))); + console.unstashLine(); + } + + @Override + public void println(double x) { + console.stashLine(); + String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); + ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + x), true); + logs.println(ChatColor.stripColor("[" + date + " Info]" + x)); + super.println(ChatColor.stripColor("[" + date + " Info]" + x)); + console.unstashLine(); + } + + @Override + public void println(float x) { + console.stashLine(); + String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); + ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + x), true); + logs.println(ChatColor.stripColor("[" + date + " Info]" + x)); + super.println(ChatColor.stripColor("[" + date + " Info]" + x)); + console.unstashLine(); + } + + @Override + public void println(int x) { + console.stashLine(); + String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); + ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + x), true); + logs.println(ChatColor.stripColor("[" + date + " Info]" + x)); + super.println(ChatColor.stripColor("[" + date + " Info]" + x)); + console.unstashLine(); + } + + @Override + public void println(long x) { + console.stashLine(); + String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); + ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + x), true); + logs.println(ChatColor.stripColor("[" + date + " Info]" + x)); + super.println(ChatColor.stripColor("[" + date + " Info]" + x)); + console.unstashLine(); + } + + @Override + public void println(Object x) { + console.stashLine(); + String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); + ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + x), true); + logs.println(ChatColor.stripColor("[" + date + " Info]" + x)); + super.println(ChatColor.stripColor("[" + date + " Info]" + x)); + console.unstashLine(); + } + + @Override + public void println(String string) { + console.stashLine(); + String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); + ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + string), true); + logs.println(ChatColor.stripColor("[" + date + " Info] " + string)); + super.println(ChatColor.stripColor("[" + date + " Info] " + string)); + console.unstashLine(); + } + } + + public static class ConsoleErrorStream extends PrintStream { + + private final PrintStream logs; + private final Console console; + + public ConsoleErrorStream(Console console, OutputStream out, PrintStream logs) { + super(out); + this.logs = logs; + this.console = console; + } + + @SuppressWarnings("resource") + @Override + public PrintStream printf(Locale l, String format, Object... args) { + console.stashLine(); + String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); + ConsoleTextOutput.appendText(ChatColor.stripColor(String.format(l, "[" + date + " Error]" + format, args))); + logs.printf(l, ChatColor.stripColor("[" + date + " Error]" + format), args); + PrintStream stream = super.printf(l, ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + format + RESET_COLOR), args); + console.unstashLine(); + return stream; + } + + @SuppressWarnings("resource") + @Override + public PrintStream printf(String format, Object... args) { + console.stashLine(); + String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); + ConsoleTextOutput.appendText(ChatColor.stripColor(String.format("[" + date + " Error]" + format, args))); + logs.printf(ChatColor.stripColor("[" + date + " Error]" + format), args); + PrintStream stream = super.printf(ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + format + RESET_COLOR), args); + console.unstashLine(); + return stream; + } + + @Override + public void println() { + console.stashLine(); + String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); + ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error]"), true); + logs.println(ChatColor.stripColor("[" + date + " Error]")); + super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]") + RESET_COLOR); + console.unstashLine(); + } + + @Override + public void println(boolean x) { + console.stashLine(); + String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); + ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + x), true); + logs.println(ChatColor.stripColor("[" + date + " Error]" + x)); + super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + x) + RESET_COLOR); + console.unstashLine(); + } + + @Override + public void println(char x) { + console.stashLine(); + String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); + ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + x), true); + logs.println(ChatColor.stripColor("[" + date + " Error]" + x)); + super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + x) + RESET_COLOR); + console.unstashLine(); + } + + @Override + public void println(char[] x) { + console.stashLine(); + String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); + ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + String.valueOf(x)), true); + logs.println(ChatColor.stripColor("[" + date + " Error]" + String.valueOf(x))); + super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + String.valueOf(x)) + RESET_COLOR); + console.unstashLine(); + } + + @Override + public void println(double x) { + console.stashLine(); + String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); + ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + x), true); + logs.println(ChatColor.stripColor("[" + date + " Error]" + x)); + super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + x) + RESET_COLOR); + console.unstashLine(); + } + + @Override + public void println(float x) { + console.stashLine(); + String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); + ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + x), true); + logs.println(ChatColor.stripColor("[" + date + " Error]" + x)); + super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + x) + RESET_COLOR); + console.unstashLine(); + } + + @Override + public void println(int x) { + console.stashLine(); + String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); + ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + x), true); + logs.println(ChatColor.stripColor("[" + date + " Error]" + x)); + super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + x) + RESET_COLOR); + console.unstashLine(); + } + + @Override + public void println(long x) { + console.stashLine(); + String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); + ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + x), true); + logs.println(ChatColor.stripColor("[" + date + " Error]" + x)); + super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + x) + RESET_COLOR); + console.unstashLine(); + } + + @Override + public void println(Object x) { + console.stashLine(); + String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); + ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + x), true); + logs.println(ChatColor.stripColor("[" + date + " Error]" + x)); + super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + x) + RESET_COLOR); + console.unstashLine(); + } + + @Override + public void println(String string) { + console.stashLine(); + String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); + ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + string), true); + logs.println(ChatColor.stripColor("[" + date + " Error] " + string)); + super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error] " + string) + RESET_COLOR); + console.unstashLine(); + } + } } diff --git a/src/main/java/com/loohp/limbo/Limbo.java b/src/main/java/com/loohp/limbo/Limbo.java index a331642..4247302 100644 --- a/src/main/java/com/loohp/limbo/Limbo.java +++ b/src/main/java/com/loohp/limbo/Limbo.java @@ -1,51 +1,10 @@ package com.loohp.limbo; -import java.awt.GraphicsEnvironment; -import java.awt.image.BufferedImage; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.URL; -import java.nio.channels.Channels; -import java.nio.channels.ReadableByteChannel; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.TreeMap; -import java.util.UUID; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Collectors; - -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; -import org.json.simple.parser.JSONParser; -import org.json.simple.parser.ParseException; - import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import com.loohp.limbo.events.EventsManager; -import com.loohp.limbo.server.ServerConnection; -import com.loohp.limbo.server.packets.Packet; -import com.loohp.limbo.server.packets.PacketIn; -import com.loohp.limbo.server.packets.PacketOut; import com.loohp.limbo.commands.CommandSender; import com.loohp.limbo.consolegui.GUI; +import com.loohp.limbo.events.EventsManager; import com.loohp.limbo.file.ServerProperties; import com.loohp.limbo.location.Location; import com.loohp.limbo.metrics.Metrics; @@ -55,6 +14,10 @@ import com.loohp.limbo.plugins.LimboPlugin; import com.loohp.limbo.plugins.PluginManager; import com.loohp.limbo.scheduler.LimboScheduler; import com.loohp.limbo.scheduler.Tick; +import com.loohp.limbo.server.ServerConnection; +import com.loohp.limbo.server.packets.Packet; +import com.loohp.limbo.server.packets.PacketIn; +import com.loohp.limbo.server.packets.PacketOut; import com.loohp.limbo.utils.CustomStringUtils; import com.loohp.limbo.utils.ImageUtils; import com.loohp.limbo.utils.NetworkUtils; @@ -62,516 +25,524 @@ import com.loohp.limbo.world.DimensionRegistry; import com.loohp.limbo.world.Environment; import com.loohp.limbo.world.Schematic; import com.loohp.limbo.world.World; - import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.chat.ComponentSerializer; import net.querz.nbt.io.NBTUtil; import net.querz.nbt.tag.CompoundTag; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.*; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URL; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.List; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; public class Limbo { - - private static Limbo instance; - public static boolean noGui = false; - - public static void main(String args[]) throws IOException, ParseException, NumberFormatException, ClassNotFoundException, InterruptedException { - for (String flag : args) { - if (flag.equals("--nogui") || flag.equals("nogui")) { - noGui = true; - } else if (flag.equals("--help")) { - System.out.println("Accepted flags:"); - System.out.println(" --nogui <- Disable the GUI"); - System.exit(0); - } else { - System.out.println("Unknown flag: \"" + flag + "\". Ignoring..."); - } - } - if (GraphicsEnvironment.isHeadless()) { - noGui = true; - } - if (!noGui) { - System.out.println("Launching Server GUI.. Add \"--nogui\" in launch arguments to disable"); - Thread t1 = new Thread(new Runnable() { - @Override - public void run() { - GUI.main(); - } - }); - t1.start(); - } - - new Limbo(); - } - - public static Limbo getInstance() { - return instance; - } - - //=========================== - - public final String serverImplementationVersion = "1.16.5"; - public final int serverImplmentationProtocol = 754; - public final String limboImplementationVersion; - - private AtomicBoolean isRunning; - - private ServerConnection server; - private Console console; - - private List worlds = new ArrayList<>(); - private Map playersByName = new HashMap<>(); - private Map playersByUUID = new HashMap<>(); - - private ServerProperties properties; - - private PluginManager pluginManager; - private EventsManager eventsManager; - private PermissionsManager permissionManager; - private File pluginFolder; - - private File internalDataFolder; - - private DimensionRegistry dimensionRegistry; - - private Tick tick; - private LimboScheduler scheduler; - - private Metrics metrics; - - public AtomicInteger entityIdCount = new AtomicInteger(); - - @SuppressWarnings("deprecation") - private Unsafe unsafe = new Unsafe(); - - @SuppressWarnings("unchecked") - public Limbo() throws IOException, ParseException, NumberFormatException, ClassNotFoundException, InterruptedException { - instance = this; - isRunning = new AtomicBoolean(true); - - if (!noGui) { - while (!GUI.loadFinish) { - TimeUnit.MILLISECONDS.sleep(500); - } - console = new Console(null, System.out, System.err); - } else { - console = new Console(System.in, System.out, System.err); - } - - limboImplementationVersion = getLimboVersion(); - console.sendMessage("Loading Limbo Version " + limboImplementationVersion + " on Minecraft " + serverImplementationVersion); - - String spName = "server.properties"; + + public static boolean noGui = false; + private static Limbo instance; + public final String serverImplementationVersion = "1.16.5"; + public final int serverImplmentationProtocol = 754; + + //=========================== + public final String limboImplementationVersion; + public AtomicInteger entityIdCount = new AtomicInteger(); + private final AtomicBoolean isRunning; + private final ServerConnection server; + private final Console console; + private final List worlds = new ArrayList<>(); + private final Map playersByName = new HashMap<>(); + private final Map playersByUUID = new HashMap<>(); + private final ServerProperties properties; + private final PluginManager pluginManager; + private final EventsManager eventsManager; + private final PermissionsManager permissionManager; + private final File pluginFolder; + private final File internalDataFolder; + private final DimensionRegistry dimensionRegistry; + private final Tick tick; + private final LimboScheduler scheduler; + private final Metrics metrics; + @SuppressWarnings("deprecation") + private final Unsafe unsafe = new Unsafe(); + + @SuppressWarnings("unchecked") + public Limbo() throws IOException, ParseException, NumberFormatException, ClassNotFoundException, InterruptedException { + instance = this; + isRunning = new AtomicBoolean(true); + + if (!noGui) { + while (!GUI.loadFinish) { + TimeUnit.MILLISECONDS.sleep(500); + } + console = new Console(null, System.out, System.err); + } else { + console = new Console(System.in, System.out, System.err); + } + + limboImplementationVersion = getLimboVersion(); + console.sendMessage("Loading Limbo Version " + limboImplementationVersion + " on Minecraft " + serverImplementationVersion); + + String spName = "server.properties"; File sp = new File(spName); if (!sp.exists()) { - try (InputStream in = getClass().getClassLoader().getResourceAsStream(spName)) { + try (InputStream in = getClass().getClassLoader().getResourceAsStream(spName)) { Files.copy(in, sp.toPath()); } catch (IOException e) { - e.printStackTrace(); + e.printStackTrace(); } } properties = new ServerProperties(sp); - + if (!properties.isBungeecord()) { - console.sendMessage("If you are using bungeecord, consider turning that on in the settings!"); + console.sendMessage("If you are using bungeecord, consider turning that on in the settings!"); } else { - console.sendMessage("Starting Limbo server in bungeecord mode!"); + console.sendMessage("Starting Limbo server in bungeecord mode!"); } - + internalDataFolder = new File("internal_data"); if (!internalDataFolder.exists()) { - internalDataFolder.mkdirs(); + internalDataFolder.mkdirs(); } - + String mappingName = "mapping.json"; File mappingFile = new File(internalDataFolder, mappingName); if (!mappingFile.exists()) { - try (InputStream in = getClass().getClassLoader().getResourceAsStream(mappingName)) { + try (InputStream in = getClass().getClassLoader().getResourceAsStream(mappingName)) { Files.copy(in, mappingFile.toPath()); } catch (IOException e) { - e.printStackTrace(); + e.printStackTrace(); } } - + console.sendMessage("Loading packet id mappings from mapping.json ..."); - + InputStreamReader reader = new InputStreamReader(new FileInputStream(mappingFile), StandardCharsets.UTF_8); JSONObject json = (JSONObject) new JSONParser().parse(reader); reader.close(); - + String classPrefix = Packet.class.getName().substring(0, Packet.class.getName().lastIndexOf(".") + 1); int mappingsCount = 0; - - Map> HandshakeIn = new HashMap<>(); - for (Object key : ((JSONObject) json.get("HandshakeIn")).keySet()) { - int packetId = Integer.decode((String) key); - HandshakeIn.put(packetId, (Class) Class.forName(classPrefix + (String) ((JSONObject) json.get("HandshakeIn")).get(key))); - } - Packet.setHandshakeIn(HandshakeIn); - mappingsCount += HandshakeIn.size(); - - Map> StatusIn = new HashMap<>(); - for (Object key : ((JSONObject) json.get("StatusIn")).keySet()) { - int packetId = Integer.decode((String) key); - StatusIn.put(packetId, (Class) Class.forName(classPrefix + (String) ((JSONObject) json.get("StatusIn")).get(key))); - } - Packet.setStatusIn(StatusIn); - mappingsCount += StatusIn.size(); - - Map, Integer> StatusOut = new HashMap<>(); - for (Object key : ((JSONObject) json.get("StatusOut")).keySet()) { - Class packetClass = (Class) Class.forName(classPrefix + (String) key); - StatusOut.put(packetClass, Integer.decode((String) ((JSONObject) json.get("StatusOut")).get(key))); - } - Packet.setStatusOut(StatusOut); - mappingsCount += StatusOut.size(); - - Map> LoginIn = new HashMap<>(); - for (Object key : ((JSONObject) json.get("LoginIn")).keySet()) { - int packetId = Integer.decode((String) key); - LoginIn.put(packetId, (Class) Class.forName(classPrefix + (String) ((JSONObject) json.get("LoginIn")).get(key))); - } - Packet.setLoginIn(LoginIn); - mappingsCount += LoginIn.size(); - - Map, Integer> LoginOut = new HashMap<>(); - for (Object key : ((JSONObject) json.get("LoginOut")).keySet()) { - Class packetClass = (Class) Class.forName(classPrefix + (String) key); - LoginOut.put(packetClass, Integer.decode((String) ((JSONObject) json.get("LoginOut")).get(key))); - } - Packet.setLoginOut(LoginOut); - mappingsCount += LoginOut.size(); - - Map> PlayIn = new HashMap<>(); - for (Object key : ((JSONObject) json.get("PlayIn")).keySet()) { - int packetId = Integer.decode((String) key); - PlayIn.put(packetId, (Class) Class.forName(classPrefix + (String) ((JSONObject) json.get("PlayIn")).get(key))); - } - Packet.setPlayIn(PlayIn); - mappingsCount += PlayIn.size(); - - Map, Integer> PlayOut = new HashMap<>(); - for (Object key : ((JSONObject) json.get("PlayOut")).keySet()) { - Class packetClass = (Class) Class.forName(classPrefix + (String) key); - PlayOut.put(packetClass, Integer.decode((String) ((JSONObject) json.get("PlayOut")).get(key))); - } - Packet.setPlayOut(PlayOut); - mappingsCount += PlayOut.size(); - - console.sendMessage("Loaded all " + mappingsCount + " packet id mappings!"); - - dimensionRegistry = new DimensionRegistry(); - - worlds.add(loadDefaultWorld()); - Location spawn = properties.getWorldSpawn(); - properties.setWorldSpawn(new Location(getWorld(properties.getLevelName().getKey()), spawn.getX(), spawn.getY(), spawn.getZ(), spawn.getYaw(), spawn.getPitch())); - - if (!NetworkUtils.available(properties.getServerPort())) { - console.sendMessage(""); - console.sendMessage("*****FAILED TO BIND PORT [" + properties.getServerPort() + "]*****"); - console.sendMessage("*****PORT ALREADY IN USE*****"); - console.sendMessage("*****PERHAPS ANOTHER INSTANCE OF THE SERVER IS ALREADY RUNNING?*****"); - console.sendMessage(""); - System.exit(2); - } - - String permissionName = "permission.yml"; + + Map> HandshakeIn = new HashMap<>(); + for (Object key : ((JSONObject) json.get("HandshakeIn")).keySet()) { + int packetId = Integer.decode((String) key); + HandshakeIn.put(packetId, (Class) Class.forName(classPrefix + ((JSONObject) json.get("HandshakeIn")).get(key))); + } + Packet.setHandshakeIn(HandshakeIn); + mappingsCount += HandshakeIn.size(); + + Map> StatusIn = new HashMap<>(); + for (Object key : ((JSONObject) json.get("StatusIn")).keySet()) { + int packetId = Integer.decode((String) key); + StatusIn.put(packetId, (Class) Class.forName(classPrefix + ((JSONObject) json.get("StatusIn")).get(key))); + } + Packet.setStatusIn(StatusIn); + mappingsCount += StatusIn.size(); + + Map, Integer> StatusOut = new HashMap<>(); + for (Object key : ((JSONObject) json.get("StatusOut")).keySet()) { + Class packetClass = (Class) Class.forName(classPrefix + key); + StatusOut.put(packetClass, Integer.decode((String) ((JSONObject) json.get("StatusOut")).get(key))); + } + Packet.setStatusOut(StatusOut); + mappingsCount += StatusOut.size(); + + Map> LoginIn = new HashMap<>(); + for (Object key : ((JSONObject) json.get("LoginIn")).keySet()) { + int packetId = Integer.decode((String) key); + LoginIn.put(packetId, (Class) Class.forName(classPrefix + ((JSONObject) json.get("LoginIn")).get(key))); + } + Packet.setLoginIn(LoginIn); + mappingsCount += LoginIn.size(); + + Map, Integer> LoginOut = new HashMap<>(); + for (Object key : ((JSONObject) json.get("LoginOut")).keySet()) { + Class packetClass = (Class) Class.forName(classPrefix + key); + LoginOut.put(packetClass, Integer.decode((String) ((JSONObject) json.get("LoginOut")).get(key))); + } + Packet.setLoginOut(LoginOut); + mappingsCount += LoginOut.size(); + + Map> PlayIn = new HashMap<>(); + for (Object key : ((JSONObject) json.get("PlayIn")).keySet()) { + int packetId = Integer.decode((String) key); + PlayIn.put(packetId, (Class) Class.forName(classPrefix + ((JSONObject) json.get("PlayIn")).get(key))); + } + Packet.setPlayIn(PlayIn); + mappingsCount += PlayIn.size(); + + Map, Integer> PlayOut = new HashMap<>(); + for (Object key : ((JSONObject) json.get("PlayOut")).keySet()) { + Class packetClass = (Class) Class.forName(classPrefix + key); + PlayOut.put(packetClass, Integer.decode((String) ((JSONObject) json.get("PlayOut")).get(key))); + } + Packet.setPlayOut(PlayOut); + mappingsCount += PlayOut.size(); + + console.sendMessage("Loaded all " + mappingsCount + " packet id mappings!"); + + dimensionRegistry = new DimensionRegistry(); + + worlds.add(loadDefaultWorld()); + Location spawn = properties.getWorldSpawn(); + properties.setWorldSpawn(new Location(getWorld(properties.getLevelName().getKey()), spawn.getX(), spawn.getY(), spawn.getZ(), spawn.getYaw(), spawn.getPitch())); + + if (!NetworkUtils.available(properties.getServerPort())) { + console.sendMessage(""); + console.sendMessage("*****FAILED TO BIND PORT [" + properties.getServerPort() + "]*****"); + console.sendMessage("*****PORT ALREADY IN USE*****"); + console.sendMessage("*****PERHAPS ANOTHER INSTANCE OF THE SERVER IS ALREADY RUNNING?*****"); + console.sendMessage(""); + System.exit(2); + } + + String permissionName = "permission.yml"; File permissionFile = new File(permissionName); if (!permissionFile.exists()) { - try (InputStream in = getClass().getClassLoader().getResourceAsStream(permissionName)) { + try (InputStream in = getClass().getClassLoader().getResourceAsStream(permissionName)) { Files.copy(in, permissionFile.toPath()); } catch (IOException e) { - e.printStackTrace(); + e.printStackTrace(); } } - + scheduler = new LimboScheduler(); - tick = new Tick(this); - + tick = new Tick(this); + permissionManager = new PermissionsManager(); - permissionManager.loadDefaultPermissionFile(permissionFile); - + permissionManager.loadDefaultPermissionFile(permissionFile); + eventsManager = new EventsManager(); - + pluginFolder = new File("plugins"); pluginFolder.mkdirs(); - + File defaultCommandsJar = new File(pluginFolder, "LimboDefaultCmd.jar"); defaultCommandsJar.delete(); console.sendMessage("Downloading limbo default commands module from github..."); ReadableByteChannel rbc = Channels.newChannel(new URL("https://github.com/LOOHP/Limbo/raw/master/modules/LimboDefaultCmd.jar").openStream()); - FileOutputStream fos = new FileOutputStream(defaultCommandsJar); - fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); - fos.close(); - - pluginManager = new PluginManager(pluginFolder); - try { - Method loadPluginsMethod = PluginManager.class.getDeclaredMethod("loadPlugins"); - loadPluginsMethod.setAccessible(true); - loadPluginsMethod.invoke(pluginManager); - loadPluginsMethod.setAccessible(false); - } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - e.printStackTrace(); - } - - for (LimboPlugin plugin : Limbo.getInstance().getPluginManager().getPlugins()) { - console.sendMessage("Enabling plugin " + plugin.getName() + " " + plugin.getInfo().getVersion()); - plugin.onEnable(); - } - - server = new ServerConnection(properties.getServerIp(), properties.getServerPort()); - - metrics = new Metrics(); - - Runtime.getRuntime().addShutdownHook(new Thread(() -> { - Limbo.getInstance().terminate(); - })); - - console.run(); - } + FileOutputStream fos = new FileOutputStream(defaultCommandsJar); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); - @Deprecated - public Unsafe getUnsafe() { - return unsafe; - } - - public Tick getHeartBeat() { - return tick; - } - - public LimboScheduler getScheduler() { - return scheduler; - } + pluginManager = new PluginManager(pluginFolder); + try { + Method loadPluginsMethod = PluginManager.class.getDeclaredMethod("loadPlugins"); + loadPluginsMethod.setAccessible(true); + loadPluginsMethod.invoke(pluginManager); + loadPluginsMethod.setAccessible(false); + } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + e.printStackTrace(); + } - public DimensionRegistry getDimensionRegistry() { - return dimensionRegistry; - } + for (LimboPlugin plugin : Limbo.getInstance().getPluginManager().getPlugins()) { + console.sendMessage("Enabling plugin " + plugin.getName() + " " + plugin.getInfo().getVersion()); + plugin.onEnable(); + } - public PermissionsManager getPermissionsManager() { - return permissionManager; - } + server = new ServerConnection(properties.getServerIp(), properties.getServerPort()); - public File getInternalDataFolder() { - return internalDataFolder; - } + metrics = new Metrics(); - public EventsManager getEventsManager() { - return eventsManager; - } - - public File getPluginFolder() { - return pluginFolder; - } - - public PluginManager getPluginManager() { - return pluginManager; - } + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + Limbo.getInstance().terminate(); + })); - private World loadDefaultWorld() throws IOException { - console.sendMessage("Loading world " + properties.getLevelName() + " with the schematic file " + properties.getSchemFileName() + " ..."); - - File schem = new File(properties.getSchemFileName()); - - if (!schem.exists()) { - console.sendMessage("Schemetic file " + properties.getSchemFileName() + " for world " + properties.getLevelName() + " not found!"); - console.sendMessage("Server will exit!"); - System.exit(1); - return null; - } - - World world = Schematic.toWorld(properties.getLevelName().getKey(), Environment.fromNamespacedKey(properties.getLevelDimension()), (CompoundTag) NBTUtil.read(schem).getTag()); - - console.sendMessage("Loaded world " + properties.getLevelName() + "!"); - - return world; - } - - public void registerWorld(World world) { - if (!worlds.contains(world)) { - worlds.add(world); - } else { - throw new RuntimeException("World already registered"); - } - } - - public void unregisterWorld(World world) { - if (worlds.indexOf(world) == 0) { - throw new RuntimeException("World already registered"); - } else if (!worlds.contains(world)) { - throw new RuntimeException("World not registered"); - } else { - for (Player player : world.getPlayers()) { - player.teleport(properties.getWorldSpawn()); - } - worlds.remove(world); - } - } - - public ServerProperties getServerProperties() { - return properties; - } - - public ServerConnection getServerConnection() { - return server; - } + console.run(); + } - public Console getConsole() { - return console; - } - - public Metrics getMetrics() { - return metrics; - } + public static void main(String[] args) throws IOException, ParseException, NumberFormatException, ClassNotFoundException, InterruptedException { + for (String flag : args) { + if (flag.equals("--nogui") || flag.equals("nogui")) { + noGui = true; + } else if (flag.equals("--help")) { + System.out.println("Accepted flags:"); + System.out.println(" --nogui <- Disable the GUI"); + System.exit(0); + } else { + System.out.println("Unknown flag: \"" + flag + "\". Ignoring..."); + } + } + if (GraphicsEnvironment.isHeadless()) { + noGui = true; + } + if (!noGui) { + System.out.println("Launching Server GUI.. Add \"--nogui\" in launch arguments to disable"); + Thread t1 = new Thread(new Runnable() { + @Override + public void run() { + GUI.main(); + } + }); + t1.start(); + } - public Set getPlayers() { - return new HashSet<>(playersByUUID.values()); - } - - public Player getPlayer(String name) { - return playersByName.get(name); - } - - public Player getPlayer(UUID uuid) { - return playersByUUID.get(uuid); - } - - public void addPlayer(Player player) { - playersByName.put(player.getName(), player); - playersByUUID.put(player.getUniqueId(), player); - } - - public void removePlayer(Player player) { - playersByName.remove(player.getName()); - playersByUUID.remove(player.getUniqueId()); - } - - public List getWorlds() { - return new ArrayList<>(worlds); - } - - public World getWorld(String name) { - for (World world : worlds) { - if (world.getName().equalsIgnoreCase(name)) { - return world; - } - } - return null; - } - - @SuppressWarnings("unchecked") - public String buildServerListResponseJson(String version, int protocol, BaseComponent[] motd, int maxPlayers, int playersOnline, BufferedImage favicon) throws IOException { - JSONObject json = new JSONObject(); + new Limbo(); + } - JSONObject versionJson = new JSONObject(); - versionJson.put("name", version); - versionJson.put("protocol", protocol); - json.put("version", versionJson); - - JSONObject playersJson = new JSONObject(); - playersJson.put("max", maxPlayers); - playersJson.put("online", playersOnline); - json.put("players", playersJson); - - json.put("description", "%MOTD%"); - - if (favicon != null) { - if (favicon.getWidth() == 64 && favicon.getHeight() == 64) { - String base64 = "data:image/png;base64," + ImageUtils.imgToBase64String(favicon, "png"); - json.put("favicon", base64); - } else { - console.sendMessage("Server List Favicon must be 64 x 64 in size!"); - } - } - - JSONObject modInfoJson = new JSONObject(); - modInfoJson.put("type", "FML"); - modInfoJson.put("modList", new JSONArray()); - json.put("modinfo", modInfoJson); - - - TreeMap treeMap = new TreeMap(String.CASE_INSENSITIVE_ORDER); - treeMap.putAll(json); - - Gson g = new GsonBuilder().create(); + public static Limbo getInstance() { + return instance; + } - return g.toJson(treeMap).replace("\"%MOTD%\"", ComponentSerializer.toString(motd)); - } - - public String buildLegacyPingResponse(String version, BaseComponent[] motd, int maxPlayers, int playersOnline) { - String begin = "§1"; - return String.join("\00", begin, "127", version, String.join("", Arrays.asList(motd).stream().map(each -> each.toLegacyText()).collect(Collectors.toList())), String.valueOf(playersOnline), String.valueOf(maxPlayers)); - } - - protected void terminate() { - isRunning.set(false); - console.sendMessage("Stopping Server..."); - - for (LimboPlugin plugin : Limbo.getInstance().getPluginManager().getPlugins()) { - console.sendMessage("Disabling plugin " + plugin.getName() + " " + plugin.getInfo().getVersion()); - plugin.onDisable(); - } - - tick.waitAndKillThreads(5000); - - for (Player player : getPlayers()) { - player.disconnect("Server closed"); - } - while (!getPlayers().isEmpty()) { - try { - TimeUnit.MILLISECONDS.sleep(500); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - console.sendMessage("Server closed"); - console.logs.close(); - } - - public void stopServer() { - System.exit(0); - } - - public boolean isRunning() { - return isRunning.get(); - } - - public int getNextEntityId() { - if (entityIdCount.get() == Integer.MAX_VALUE) { - return entityIdCount.getAndSet(0); - } else { - return entityIdCount.getAndIncrement(); - } - } - - public void dispatchCommand(CommandSender sender, String str) { - String[] command; - if (str.startsWith("/")) { - command = CustomStringUtils.splitStringToArgs(str.substring(1)); - } else { - command = CustomStringUtils.splitStringToArgs(str); - } - dispatchCommand(sender, command); - } - - public void dispatchCommand(CommandSender sender, String... args) { - try { - Limbo.getInstance().getPluginManager().fireExecutors(sender, args); - } catch (Exception e) { - e.printStackTrace(); - } - } - - private String getLimboVersion() throws IOException { - Enumeration manifests = getClass().getClassLoader().getResources("META-INF/MANIFEST.MF"); - while (manifests.hasMoreElements()) { - URL url = manifests.nextElement(); - BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream())); - Optional line = br.lines().filter(each -> each.startsWith("Limbo-Version:")).findFirst(); - br.close(); - if (line.isPresent()) { - return line.get().substring(14).trim(); - } - } - return "Unknown"; - } + @Deprecated + public Unsafe getUnsafe() { + return unsafe; + } + + public Tick getHeartBeat() { + return tick; + } + + public LimboScheduler getScheduler() { + return scheduler; + } + + public DimensionRegistry getDimensionRegistry() { + return dimensionRegistry; + } + + public PermissionsManager getPermissionsManager() { + return permissionManager; + } + + public File getInternalDataFolder() { + return internalDataFolder; + } + + public EventsManager getEventsManager() { + return eventsManager; + } + + public File getPluginFolder() { + return pluginFolder; + } + + public PluginManager getPluginManager() { + return pluginManager; + } + + private World loadDefaultWorld() throws IOException { + console.sendMessage("Loading world " + properties.getLevelName() + " with the schematic file " + properties.getSchemFileName() + " ..."); + + File schem = new File(properties.getSchemFileName()); + + if (!schem.exists()) { + console.sendMessage("Schemetic file " + properties.getSchemFileName() + " for world " + properties.getLevelName() + " not found!"); + console.sendMessage("Server will exit!"); + System.exit(1); + return null; + } + + World world = Schematic.toWorld(properties.getLevelName().getKey(), Environment.fromNamespacedKey(properties.getLevelDimension()), (CompoundTag) NBTUtil.read(schem).getTag()); + + console.sendMessage("Loaded world " + properties.getLevelName() + "!"); + + return world; + } + + public void registerWorld(World world) { + if (!worlds.contains(world)) { + worlds.add(world); + } else { + throw new RuntimeException("World already registered"); + } + } + + public void unregisterWorld(World world) { + if (worlds.indexOf(world) == 0) { + throw new RuntimeException("World already registered"); + } else if (!worlds.contains(world)) { + throw new RuntimeException("World not registered"); + } else { + for (Player player : world.getPlayers()) { + player.teleport(properties.getWorldSpawn()); + } + worlds.remove(world); + } + } + + public ServerProperties getServerProperties() { + return properties; + } + + public ServerConnection getServerConnection() { + return server; + } + + public Console getConsole() { + return console; + } + + public Metrics getMetrics() { + return metrics; + } + + public Set getPlayers() { + return new HashSet<>(playersByUUID.values()); + } + + public Player getPlayer(String name) { + return playersByName.get(name); + } + + public Player getPlayer(UUID uuid) { + return playersByUUID.get(uuid); + } + + public void addPlayer(Player player) { + playersByName.put(player.getName(), player); + playersByUUID.put(player.getUniqueId(), player); + } + + public void removePlayer(Player player) { + playersByName.remove(player.getName()); + playersByUUID.remove(player.getUniqueId()); + } + + public List getWorlds() { + return new ArrayList<>(worlds); + } + + public World getWorld(String name) { + for (World world : worlds) { + if (world.getName().equalsIgnoreCase(name)) { + return world; + } + } + return null; + } + + @SuppressWarnings("unchecked") + public String buildServerListResponseJson(String version, int protocol, BaseComponent[] motd, int maxPlayers, int playersOnline, BufferedImage favicon) throws IOException { + JSONObject json = new JSONObject(); + + JSONObject versionJson = new JSONObject(); + versionJson.put("name", version); + versionJson.put("protocol", protocol); + json.put("version", versionJson); + + JSONObject playersJson = new JSONObject(); + playersJson.put("max", maxPlayers); + playersJson.put("online", playersOnline); + json.put("players", playersJson); + + json.put("description", "%MOTD%"); + + if (favicon != null) { + if (favicon.getWidth() == 64 && favicon.getHeight() == 64) { + String base64 = "data:image/png;base64," + ImageUtils.imgToBase64String(favicon, "png"); + json.put("favicon", base64); + } else { + console.sendMessage("Server List Favicon must be 64 x 64 in size!"); + } + } + + JSONObject modInfoJson = new JSONObject(); + modInfoJson.put("type", "FML"); + modInfoJson.put("modList", new JSONArray()); + json.put("modinfo", modInfoJson); + + + TreeMap treeMap = new TreeMap(String.CASE_INSENSITIVE_ORDER); + treeMap.putAll(json); + + Gson g = new GsonBuilder().create(); + + return g.toJson(treeMap).replace("\"%MOTD%\"", ComponentSerializer.toString(motd)); + } + + public String buildLegacyPingResponse(String version, BaseComponent[] motd, int maxPlayers, int playersOnline) { + String begin = "�1"; + return String.join("\00", begin, "127", version, String.join("", Arrays.asList(motd).stream().map(each -> each.toLegacyText()).collect(Collectors.toList())), String.valueOf(playersOnline), String.valueOf(maxPlayers)); + } + + protected void terminate() { + isRunning.set(false); + console.sendMessage("Stopping Server..."); + + for (LimboPlugin plugin : Limbo.getInstance().getPluginManager().getPlugins()) { + console.sendMessage("Disabling plugin " + plugin.getName() + " " + plugin.getInfo().getVersion()); + plugin.onDisable(); + } + + tick.waitAndKillThreads(5000); + + for (Player player : getPlayers()) { + player.disconnect("Server closed"); + } + while (!getPlayers().isEmpty()) { + try { + TimeUnit.MILLISECONDS.sleep(500); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + console.sendMessage("Server closed"); + console.logs.close(); + } + + public void stopServer() { + System.exit(0); + } + + public boolean isRunning() { + return isRunning.get(); + } + + public int getNextEntityId() { + if (entityIdCount.get() == Integer.MAX_VALUE) { + return entityIdCount.getAndSet(0); + } else { + return entityIdCount.getAndIncrement(); + } + } + + public void dispatchCommand(CommandSender sender, String str) { + String[] command; + if (str.startsWith("/")) { + command = CustomStringUtils.splitStringToArgs(str.substring(1)); + } else { + command = CustomStringUtils.splitStringToArgs(str); + } + dispatchCommand(sender, command); + } + + public void dispatchCommand(CommandSender sender, String... args) { + try { + Limbo.getInstance().getPluginManager().fireExecutors(sender, args); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private String getLimboVersion() throws IOException { + Enumeration manifests = getClass().getClassLoader().getResources("META-INF/MANIFEST.MF"); + while (manifests.hasMoreElements()) { + URL url = manifests.nextElement(); + BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream())); + Optional line = br.lines().filter(each -> each.startsWith("Limbo-Version:")).findFirst(); + br.close(); + if (line.isPresent()) { + return line.get().substring(14).trim(); + } + } + return "Unknown"; + } } diff --git a/src/main/java/com/loohp/limbo/Unsafe.java b/src/main/java/com/loohp/limbo/Unsafe.java index 48ae55e..84623eb 100644 --- a/src/main/java/com/loohp/limbo/Unsafe.java +++ b/src/main/java/com/loohp/limbo/Unsafe.java @@ -1,7 +1,5 @@ package com.loohp.limbo; -import java.lang.reflect.Constructor; - import com.loohp.limbo.entity.DataWatcher; import com.loohp.limbo.entity.Entity; import com.loohp.limbo.location.Location; @@ -9,54 +7,58 @@ import com.loohp.limbo.player.Player; import com.loohp.limbo.utils.GameMode; import com.loohp.limbo.world.World; +import java.lang.reflect.Constructor; + @Deprecated public class Unsafe { - - private com.loohp.limbo.player.Unsafe playerUnsafe; - private com.loohp.limbo.world.Unsafe worldUnsafe; - - protected Unsafe() { - try { - Constructor playerConstructor = com.loohp.limbo.player.Unsafe.class.getDeclaredConstructor(); - playerConstructor.setAccessible(true); - playerUnsafe = playerConstructor.newInstance(); - playerConstructor.setAccessible(false); - - Constructor worldConstructor = com.loohp.limbo.world.Unsafe.class.getDeclaredConstructor(); - worldConstructor.setAccessible(true); - worldUnsafe = worldConstructor.newInstance(); - worldConstructor.setAccessible(false); - } catch (Exception e) {e.printStackTrace();} - } - @Deprecated - public void setPlayerGameModeSilently(Player player, GameMode mode) { - playerUnsafe.a(player, mode); - } + private com.loohp.limbo.player.Unsafe playerUnsafe; + private com.loohp.limbo.world.Unsafe worldUnsafe; - @Deprecated - public void setSelectedSlotSilently(Player player, byte slot) { - playerUnsafe.a(player, slot); - } + protected Unsafe() { + try { + Constructor playerConstructor = com.loohp.limbo.player.Unsafe.class.getDeclaredConstructor(); + playerConstructor.setAccessible(true); + playerUnsafe = playerConstructor.newInstance(); + playerConstructor.setAccessible(false); - @Deprecated - public void setPlayerEntityId(Player player, int entityId) { - playerUnsafe.a(player, entityId); - } - - @Deprecated - public void removeEntity(World world, Entity entity) { - worldUnsafe.a(world, entity); - } - - @Deprecated - public DataWatcher getDataWatcher(World world, Entity entity) { - return worldUnsafe.b(world, entity); - } - - @Deprecated - public void setPlayerLocationSilently(Player player, Location location) { - playerUnsafe.a(player, location); - } + Constructor worldConstructor = com.loohp.limbo.world.Unsafe.class.getDeclaredConstructor(); + worldConstructor.setAccessible(true); + worldUnsafe = worldConstructor.newInstance(); + worldConstructor.setAccessible(false); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Deprecated + public void setPlayerGameModeSilently(Player player, GameMode mode) { + playerUnsafe.a(player, mode); + } + + @Deprecated + public void setSelectedSlotSilently(Player player, byte slot) { + playerUnsafe.a(player, slot); + } + + @Deprecated + public void setPlayerEntityId(Player player, int entityId) { + playerUnsafe.a(player, entityId); + } + + @Deprecated + public void removeEntity(World world, Entity entity) { + worldUnsafe.a(world, entity); + } + + @Deprecated + public DataWatcher getDataWatcher(World world, Entity entity) { + return worldUnsafe.b(world, entity); + } + + @Deprecated + public void setPlayerLocationSilently(Player player, Location location) { + playerUnsafe.a(player, location); + } } diff --git a/src/main/java/com/loohp/limbo/commands/CommandExecutor.java b/src/main/java/com/loohp/limbo/commands/CommandExecutor.java index 10642fa..ebac7a1 100644 --- a/src/main/java/com/loohp/limbo/commands/CommandExecutor.java +++ b/src/main/java/com/loohp/limbo/commands/CommandExecutor.java @@ -1,7 +1,7 @@ package com.loohp.limbo.commands; public interface CommandExecutor { - - public void execute(CommandSender sender, String[] args); + + void execute(CommandSender sender, String[] args); } diff --git a/src/main/java/com/loohp/limbo/commands/CommandSender.java b/src/main/java/com/loohp/limbo/commands/CommandSender.java index 7b7ecc0..e0d03e3 100644 --- a/src/main/java/com/loohp/limbo/commands/CommandSender.java +++ b/src/main/java/com/loohp/limbo/commands/CommandSender.java @@ -1,25 +1,25 @@ package com.loohp.limbo.commands; -import java.util.UUID; - import net.md_5.bungee.api.chat.BaseComponent; +import java.util.UUID; + public interface CommandSender { - - public void sendMessage(BaseComponent[] component, UUID uuid); - - public void sendMessage(BaseComponent component, UUID uuid); - - public void sendMessage(String message, UUID uuid); - - public void sendMessage(BaseComponent[] component); - - public void sendMessage(BaseComponent component); - - public void sendMessage(String message); - - public boolean hasPermission(String permission); - - public String getName(); + + void sendMessage(BaseComponent[] component, UUID uuid); + + void sendMessage(BaseComponent component, UUID uuid); + + void sendMessage(String message, UUID uuid); + + void sendMessage(BaseComponent[] component); + + void sendMessage(BaseComponent component); + + void sendMessage(String message); + + boolean hasPermission(String permission); + + String getName(); } diff --git a/src/main/java/com/loohp/limbo/commands/TabCompletor.java b/src/main/java/com/loohp/limbo/commands/TabCompletor.java index 9be7014..1191c70 100644 --- a/src/main/java/com/loohp/limbo/commands/TabCompletor.java +++ b/src/main/java/com/loohp/limbo/commands/TabCompletor.java @@ -3,7 +3,7 @@ package com.loohp.limbo.commands; import java.util.List; public interface TabCompletor { - - public List tabComplete(CommandSender sender, String[] args); + + List tabComplete(CommandSender sender, String[] args); } diff --git a/src/main/java/com/loohp/limbo/consolegui/ConsoleTextOutput.java b/src/main/java/com/loohp/limbo/consolegui/ConsoleTextOutput.java index af2a2eb..80aee31 100644 --- a/src/main/java/com/loohp/limbo/consolegui/ConsoleTextOutput.java +++ b/src/main/java/com/loohp/limbo/consolegui/ConsoleTextOutput.java @@ -3,20 +3,20 @@ package com.loohp.limbo.consolegui; import com.loohp.limbo.Limbo; public class ConsoleTextOutput { - - public static void appendText(String string) { - if (!Limbo.noGui) { - GUI.textOutput.setText(GUI.textOutput.getText() + string); - GUI.scrollPane.getVerticalScrollBar().setValue(GUI.scrollPane.getVerticalScrollBar().getMaximum()); - } - } - - public static void appendText(String string, boolean isWriteLine) { - if (isWriteLine) { - appendText(string + "\n"); - } else { - appendText(string); - } - } + + public static void appendText(String string) { + if (!Limbo.noGui) { + GUI.textOutput.setText(GUI.textOutput.getText() + string); + GUI.scrollPane.getVerticalScrollBar().setValue(GUI.scrollPane.getVerticalScrollBar().getMaximum()); + } + } + + public static void appendText(String string, boolean isWriteLine) { + if (isWriteLine) { + appendText(string + "\n"); + } else { + appendText(string); + } + } } diff --git a/src/main/java/com/loohp/limbo/consolegui/GUI.java b/src/main/java/com/loohp/limbo/consolegui/GUI.java index 1502ae8..246e0fc 100644 --- a/src/main/java/com/loohp/limbo/consolegui/GUI.java +++ b/src/main/java/com/loohp/limbo/consolegui/GUI.java @@ -1,220 +1,205 @@ package com.loohp.limbo.consolegui; -import java.awt.Font; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Insets; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; +import com.loohp.limbo.Limbo; + +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import java.awt.*; +import java.awt.event.*; import java.util.ArrayList; import java.util.List; -import javax.swing.JButton; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTextField; -import javax.swing.JTextPane; -import javax.swing.border.EmptyBorder; - -import com.loohp.limbo.Limbo; - @SuppressWarnings("serial") public class GUI extends JFrame { - public static JPanel contentPane; - public static JTextField commandInput; - public static JButton execCommand; - public static JTextPane textOutput; - public static JScrollPane scrollPane; - public static JLabel consoleLabel; - public static JLabel clientLabel; - public static JTextPane clientText; - public static JScrollPane scrollPane_client; - public static JLabel sysLabel; - public static JScrollPane scrollPane_sys; - public static JTextPane sysText; - - public static List history = new ArrayList(); - public static int currenthistory = 0; - - public static boolean loadFinish = false; + public static JPanel contentPane; + public static JTextField commandInput; + public static JButton execCommand; + public static JTextPane textOutput; + public static JScrollPane scrollPane; + public static JLabel consoleLabel; + public static JLabel clientLabel; + public static JTextPane clientText; + public static JScrollPane scrollPane_client; + public static JLabel sysLabel; + public static JScrollPane scrollPane_sys; + public static JTextPane sysText; - /** - * Launch the application. - */ - public static void main() { - GUI frame = new GUI(); - frame.setVisible(true); - - Thread t1 = new Thread(new Runnable() { - @Override - public void run() { - SystemInfo.printInfo(); - } - }); - t1.start(); - - loadFinish = true; - } + public static List history = new ArrayList(); + public static int currenthistory = 0; - /** - * Create the frame. - */ - public GUI() { - setTitle("Limbo Minecraft Server"); - addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(WindowEvent e) { - if (Limbo.getInstance().isRunning()) { - Limbo.getInstance().stopServer(); - } - } - }); - setBounds(100, 100, 1198, 686); - contentPane = new JPanel(); - contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); - setContentPane(contentPane); - GridBagLayout gbl_contentPane = new GridBagLayout(); - gbl_contentPane.columnWidths = new int[]{243, 10, 36, 111, 0}; - gbl_contentPane.rowHeights = new int[]{0, 160, 0, 10, 33, 33, 0}; - gbl_contentPane.columnWeights = new double[]{0.0, 0.0, 1.0, 0.0, Double.MIN_VALUE}; - gbl_contentPane.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 1.0, 0.0, Double.MIN_VALUE}; - contentPane.setLayout(gbl_contentPane); - - sysLabel = new JLabel("System Information"); - sysLabel.setFont(new Font("Arial", Font.BOLD, 11)); - GridBagConstraints gbc_sysLabel = new GridBagConstraints(); - gbc_sysLabel.fill = GridBagConstraints.BOTH; - gbc_sysLabel.insets = new Insets(0, 0, 5, 5); - gbc_sysLabel.gridx = 0; - gbc_sysLabel.gridy = 0; - contentPane.add(sysLabel, gbc_sysLabel); - - consoleLabel = new JLabel("Console Output"); - consoleLabel.setFont(new Font("Arial", Font.BOLD, 11)); - GridBagConstraints gbc_consoleLabel = new GridBagConstraints(); - gbc_consoleLabel.anchor = GridBagConstraints.WEST; - gbc_consoleLabel.insets = new Insets(0, 0, 5, 5); - gbc_consoleLabel.gridx = 2; - gbc_consoleLabel.gridy = 0; - contentPane.add(consoleLabel, gbc_consoleLabel); - - commandInput = new JTextField(); - commandInput.setToolTipText("Input a command"); - commandInput.addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(KeyEvent e) { - if (e.getKeyCode() == 10) { - String cmd = commandInput.getText(); - if (!commandInput.getText().equals("")) { - history.add(cmd); - currenthistory = history.size(); - } - Limbo.getInstance().dispatchCommand(Limbo.getInstance().getConsole(), cmd.trim().replaceAll(" +", " ")); - commandInput.setText(""); - } else if (e.getKeyCode() == 38) { - currenthistory--; - if (currenthistory >= 0) { - commandInput.setText(history.get(currenthistory)); - } else { - currenthistory++; - } - } else if (e.getKeyCode() == 40) { - currenthistory++; - if (currenthistory < history.size()) { - commandInput.setText(history.get(currenthistory)); - } else { - currenthistory--; - } - } - } - }); - - scrollPane_sys = new JScrollPane(); - GridBagConstraints gbc_scrollPane_sys = new GridBagConstraints(); - gbc_scrollPane_sys.insets = new Insets(0, 0, 5, 5); - gbc_scrollPane_sys.fill = GridBagConstraints.BOTH; - gbc_scrollPane_sys.gridx = 0; - gbc_scrollPane_sys.gridy = 1; - contentPane.add(scrollPane_sys, gbc_scrollPane_sys); - - sysText = new JTextPane(); - sysText.setFont(new Font("Consolas", Font.PLAIN, 12)); - sysText.setEditable(false); - scrollPane_sys.setViewportView(sysText); - - clientLabel = new JLabel("Connected Clients"); - clientLabel.setFont(new Font("Arial", Font.BOLD, 11)); - GridBagConstraints gbc_clientLabel = new GridBagConstraints(); - gbc_clientLabel.anchor = GridBagConstraints.WEST; - gbc_clientLabel.insets = new Insets(0, 0, 5, 5); - gbc_clientLabel.gridx = 0; - gbc_clientLabel.gridy = 3; - contentPane.add(clientLabel, gbc_clientLabel); - - scrollPane_client = new JScrollPane(); - GridBagConstraints gbc_scrollPane_client = new GridBagConstraints(); - gbc_scrollPane_client.fill = GridBagConstraints.BOTH; - gbc_scrollPane_client.gridheight = 2; - gbc_scrollPane_client.insets = new Insets(0, 0, 0, 5); - gbc_scrollPane_client.gridx = 0; - gbc_scrollPane_client.gridy = 4; - contentPane.add(scrollPane_client, gbc_scrollPane_client); - - clientText = new JTextPane(); - scrollPane_client.setViewportView(clientText); - clientText.setFont(new Font("Consolas", Font.PLAIN, 12)); - clientText.setEditable(false); - - scrollPane = new JScrollPane(); - GridBagConstraints gbc_scrollPane = new GridBagConstraints(); - gbc_scrollPane.gridheight = 4; - gbc_scrollPane.insets = new Insets(0, 0, 5, 0); - gbc_scrollPane.gridwidth = 2; - gbc_scrollPane.fill = GridBagConstraints.BOTH; - gbc_scrollPane.gridx = 2; - gbc_scrollPane.gridy = 1; - contentPane.add(scrollPane, gbc_scrollPane); - - textOutput = new JTextPane(); - scrollPane.setViewportView(textOutput); - textOutput.setFont(new Font("Consolas", Font.PLAIN, 12)); - textOutput.setEditable(false); - commandInput.setFont(new Font("Tahoma", Font.PLAIN, 19)); - GridBagConstraints gbc_commandInput = new GridBagConstraints(); - gbc_commandInput.insets = new Insets(0, 0, 0, 5); - gbc_commandInput.fill = GridBagConstraints.BOTH; - gbc_commandInput.gridx = 2; - gbc_commandInput.gridy = 5; - contentPane.add(commandInput, gbc_commandInput); - commandInput.setColumns(10); - - execCommand = new JButton("RUN"); - execCommand.setToolTipText("Execute a command"); - execCommand.addMouseListener(new MouseAdapter() { - @Override - public void mouseReleased(MouseEvent e) { - String cmd = commandInput.getText(); - if (!commandInput.getText().equals("")) { - history.add(cmd); - currenthistory = history.size(); - } - Limbo.getInstance().dispatchCommand(Limbo.getInstance().getConsole(), cmd.trim().replaceAll(" +", " ")); - commandInput.setText(""); - } - }); - execCommand.setFont(new Font("Tahoma", Font.PLAIN, 19)); - GridBagConstraints gbc_execCommand = new GridBagConstraints(); - gbc_execCommand.fill = GridBagConstraints.BOTH; - gbc_execCommand.gridx = 3; - gbc_execCommand.gridy = 5; - contentPane.add(execCommand, gbc_execCommand); - } + public static boolean loadFinish = false; + + /** + * Create the frame. + */ + public GUI() { + setTitle("Limbo Minecraft Server"); + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + if (Limbo.getInstance().isRunning()) { + Limbo.getInstance().stopServer(); + } + } + }); + setBounds(100, 100, 1198, 686); + contentPane = new JPanel(); + contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); + setContentPane(contentPane); + GridBagLayout gbl_contentPane = new GridBagLayout(); + gbl_contentPane.columnWidths = new int[]{243, 10, 36, 111, 0}; + gbl_contentPane.rowHeights = new int[]{0, 160, 0, 10, 33, 33, 0}; + gbl_contentPane.columnWeights = new double[]{0.0, 0.0, 1.0, 0.0, Double.MIN_VALUE}; + gbl_contentPane.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 1.0, 0.0, Double.MIN_VALUE}; + contentPane.setLayout(gbl_contentPane); + + sysLabel = new JLabel("System Information"); + sysLabel.setFont(new Font("Arial", Font.BOLD, 11)); + GridBagConstraints gbc_sysLabel = new GridBagConstraints(); + gbc_sysLabel.fill = GridBagConstraints.BOTH; + gbc_sysLabel.insets = new Insets(0, 0, 5, 5); + gbc_sysLabel.gridx = 0; + gbc_sysLabel.gridy = 0; + contentPane.add(sysLabel, gbc_sysLabel); + + consoleLabel = new JLabel("Console Output"); + consoleLabel.setFont(new Font("Arial", Font.BOLD, 11)); + GridBagConstraints gbc_consoleLabel = new GridBagConstraints(); + gbc_consoleLabel.anchor = GridBagConstraints.WEST; + gbc_consoleLabel.insets = new Insets(0, 0, 5, 5); + gbc_consoleLabel.gridx = 2; + gbc_consoleLabel.gridy = 0; + contentPane.add(consoleLabel, gbc_consoleLabel); + + commandInput = new JTextField(); + commandInput.setToolTipText("Input a command"); + commandInput.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == 10) { + String cmd = commandInput.getText(); + if (!commandInput.getText().equals("")) { + history.add(cmd); + currenthistory = history.size(); + } + Limbo.getInstance().dispatchCommand(Limbo.getInstance().getConsole(), cmd.trim().replaceAll(" +", " ")); + commandInput.setText(""); + } else if (e.getKeyCode() == 38) { + currenthistory--; + if (currenthistory >= 0) { + commandInput.setText(history.get(currenthistory)); + } else { + currenthistory++; + } + } else if (e.getKeyCode() == 40) { + currenthistory++; + if (currenthistory < history.size()) { + commandInput.setText(history.get(currenthistory)); + } else { + currenthistory--; + } + } + } + }); + + scrollPane_sys = new JScrollPane(); + GridBagConstraints gbc_scrollPane_sys = new GridBagConstraints(); + gbc_scrollPane_sys.insets = new Insets(0, 0, 5, 5); + gbc_scrollPane_sys.fill = GridBagConstraints.BOTH; + gbc_scrollPane_sys.gridx = 0; + gbc_scrollPane_sys.gridy = 1; + contentPane.add(scrollPane_sys, gbc_scrollPane_sys); + + sysText = new JTextPane(); + sysText.setFont(new Font("Consolas", Font.PLAIN, 12)); + sysText.setEditable(false); + scrollPane_sys.setViewportView(sysText); + + clientLabel = new JLabel("Connected Clients"); + clientLabel.setFont(new Font("Arial", Font.BOLD, 11)); + GridBagConstraints gbc_clientLabel = new GridBagConstraints(); + gbc_clientLabel.anchor = GridBagConstraints.WEST; + gbc_clientLabel.insets = new Insets(0, 0, 5, 5); + gbc_clientLabel.gridx = 0; + gbc_clientLabel.gridy = 3; + contentPane.add(clientLabel, gbc_clientLabel); + + scrollPane_client = new JScrollPane(); + GridBagConstraints gbc_scrollPane_client = new GridBagConstraints(); + gbc_scrollPane_client.fill = GridBagConstraints.BOTH; + gbc_scrollPane_client.gridheight = 2; + gbc_scrollPane_client.insets = new Insets(0, 0, 0, 5); + gbc_scrollPane_client.gridx = 0; + gbc_scrollPane_client.gridy = 4; + contentPane.add(scrollPane_client, gbc_scrollPane_client); + + clientText = new JTextPane(); + scrollPane_client.setViewportView(clientText); + clientText.setFont(new Font("Consolas", Font.PLAIN, 12)); + clientText.setEditable(false); + + scrollPane = new JScrollPane(); + GridBagConstraints gbc_scrollPane = new GridBagConstraints(); + gbc_scrollPane.gridheight = 4; + gbc_scrollPane.insets = new Insets(0, 0, 5, 0); + gbc_scrollPane.gridwidth = 2; + gbc_scrollPane.fill = GridBagConstraints.BOTH; + gbc_scrollPane.gridx = 2; + gbc_scrollPane.gridy = 1; + contentPane.add(scrollPane, gbc_scrollPane); + + textOutput = new JTextPane(); + scrollPane.setViewportView(textOutput); + textOutput.setFont(new Font("Consolas", Font.PLAIN, 12)); + textOutput.setEditable(false); + commandInput.setFont(new Font("Tahoma", Font.PLAIN, 19)); + GridBagConstraints gbc_commandInput = new GridBagConstraints(); + gbc_commandInput.insets = new Insets(0, 0, 0, 5); + gbc_commandInput.fill = GridBagConstraints.BOTH; + gbc_commandInput.gridx = 2; + gbc_commandInput.gridy = 5; + contentPane.add(commandInput, gbc_commandInput); + commandInput.setColumns(10); + + execCommand = new JButton("RUN"); + execCommand.setToolTipText("Execute a command"); + execCommand.addMouseListener(new MouseAdapter() { + @Override + public void mouseReleased(MouseEvent e) { + String cmd = commandInput.getText(); + if (!commandInput.getText().equals("")) { + history.add(cmd); + currenthistory = history.size(); + } + Limbo.getInstance().dispatchCommand(Limbo.getInstance().getConsole(), cmd.trim().replaceAll(" +", " ")); + commandInput.setText(""); + } + }); + execCommand.setFont(new Font("Tahoma", Font.PLAIN, 19)); + GridBagConstraints gbc_execCommand = new GridBagConstraints(); + gbc_execCommand.fill = GridBagConstraints.BOTH; + gbc_execCommand.gridx = 3; + gbc_execCommand.gridy = 5; + contentPane.add(execCommand, gbc_execCommand); + } + + /** + * Launch the application. + */ + public static void main() { + GUI frame = new GUI(); + frame.setVisible(true); + + Thread t1 = new Thread(new Runnable() { + @Override + public void run() { + SystemInfo.printInfo(); + } + }); + t1.start(); + + loadFinish = true; + } } diff --git a/src/main/java/com/loohp/limbo/consolegui/SystemInfo.java b/src/main/java/com/loohp/limbo/consolegui/SystemInfo.java index a7ce364..e08e0b9 100644 --- a/src/main/java/com/loohp/limbo/consolegui/SystemInfo.java +++ b/src/main/java/com/loohp/limbo/consolegui/SystemInfo.java @@ -1,49 +1,53 @@ package com.loohp.limbo.consolegui; +import com.loohp.limbo.Limbo; + import java.lang.management.ManagementFactory; import java.text.NumberFormat; import java.util.concurrent.TimeUnit; -import com.loohp.limbo.Limbo; - public class SystemInfo { - - public static void printInfo() { - if (!Limbo.noGui) { - while (true) { - Runtime runtime = Runtime.getRuntime(); - NumberFormat format = NumberFormat.getInstance(); + public static void printInfo() { + if (!Limbo.noGui) { + while (true) { + Runtime runtime = Runtime.getRuntime(); - StringBuilder sb = new StringBuilder(); - long maxMemory = runtime.maxMemory(); - long allocatedMemory = runtime.totalMemory(); - long freeMemory = runtime.freeMemory(); + NumberFormat format = NumberFormat.getInstance(); - sb.append("Free Memory: " + format.format(freeMemory / 1024 / 1024) + " MB\n"); - sb.append("Allocated Memory: " + format.format(allocatedMemory / 1024 / 1024) + " MB\n"); - sb.append("Max Memory: " + format.format(maxMemory / 1024 / 1024) + " MB\n"); - sb.append("Memory Usage: " + format.format((allocatedMemory - freeMemory) / 1024 / 1024) + "/" + format.format(maxMemory / 1024 / 1024) + " MB (" + Math.round((double) (allocatedMemory - freeMemory) / (double) (maxMemory) * 100) + "%)\n"); - sb.append("\n"); + StringBuilder sb = new StringBuilder(); + long maxMemory = runtime.maxMemory(); + long allocatedMemory = runtime.totalMemory(); + long freeMemory = runtime.freeMemory(); - try { - @SuppressWarnings("restriction") - com.sun.management.OperatingSystemMXBean operatingSystemMXBean = (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean(); - @SuppressWarnings("restriction") - double processLoad = operatingSystemMXBean.getProcessCpuLoad(); - @SuppressWarnings("restriction") - double systemLoad = operatingSystemMXBean.getSystemCpuLoad(); - int processors = runtime.availableProcessors(); - - sb.append("Available Processors: " + processors + "\n"); - sb.append("Process CPU Load: " + Math.round(processLoad * 100) + "%\n"); - sb.append("System CPU Load: " + Math.round(systemLoad * 100) + "%\n"); - GUI.sysText.setText(sb.toString()); - } catch (Exception ignore) {} - - try {TimeUnit.MILLISECONDS.sleep(1000);} catch (InterruptedException e) {} - } - } - } + sb.append("Free Memory: " + format.format(freeMemory / 1024 / 1024) + " MB\n"); + sb.append("Allocated Memory: " + format.format(allocatedMemory / 1024 / 1024) + " MB\n"); + sb.append("Max Memory: " + format.format(maxMemory / 1024 / 1024) + " MB\n"); + sb.append("Memory Usage: " + format.format((allocatedMemory - freeMemory) / 1024 / 1024) + "/" + format.format(maxMemory / 1024 / 1024) + " MB (" + Math.round((double) (allocatedMemory - freeMemory) / (double) (maxMemory) * 100) + "%)\n"); + sb.append("\n"); + + try { + @SuppressWarnings("restriction") + com.sun.management.OperatingSystemMXBean operatingSystemMXBean = (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean(); + @SuppressWarnings("restriction") + double processLoad = operatingSystemMXBean.getProcessCpuLoad(); + @SuppressWarnings("restriction") + double systemLoad = operatingSystemMXBean.getSystemCpuLoad(); + int processors = runtime.availableProcessors(); + + sb.append("Available Processors: " + processors + "\n"); + sb.append("Process CPU Load: " + Math.round(processLoad * 100) + "%\n"); + sb.append("System CPU Load: " + Math.round(systemLoad * 100) + "%\n"); + GUI.sysText.setText(sb.toString()); + } catch (Exception ignore) { + } + + try { + TimeUnit.MILLISECONDS.sleep(1000); + } catch (InterruptedException e) { + } + } + } + } } diff --git a/src/main/java/com/loohp/limbo/entity/ArmorStand.java b/src/main/java/com/loohp/limbo/entity/ArmorStand.java index 5f84f0a..8ca306e 100644 --- a/src/main/java/com/loohp/limbo/entity/ArmorStand.java +++ b/src/main/java/com/loohp/limbo/entity/ArmorStand.java @@ -1,7 +1,5 @@ package com.loohp.limbo.entity; -import java.util.UUID; - import com.loohp.limbo.Limbo; import com.loohp.limbo.entity.DataWatcher.WatchableField; import com.loohp.limbo.entity.DataWatcher.WatchableObjectType; @@ -9,127 +7,129 @@ import com.loohp.limbo.location.Location; import com.loohp.limbo.utils.Rotation3f; import com.loohp.limbo.world.World; +import java.util.UUID; + public class ArmorStand extends LivingEntity { - - @WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x01) - protected boolean small = false; - @WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x04) - protected boolean arms = false; - @WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x08) - protected boolean noBasePlate = false; - @WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x10) - protected boolean marker = false; - @WatchableField(MetadataIndex = 15, WatchableObjectType = WatchableObjectType.ROTATION) - protected Rotation3f headRotation = new Rotation3f(0.0, 0.0, 0.0); - @WatchableField(MetadataIndex = 16, WatchableObjectType = WatchableObjectType.ROTATION) - protected Rotation3f bodyRotation = new Rotation3f(0.0, 0.0, 0.0); - @WatchableField(MetadataIndex = 17, WatchableObjectType = WatchableObjectType.ROTATION) - protected Rotation3f leftArmRotation = new Rotation3f(-10.0, 0.0, -10.0); - @WatchableField(MetadataIndex = 18, WatchableObjectType = WatchableObjectType.ROTATION) - protected Rotation3f rightArmRotation = new Rotation3f(-15.0, 0.0, 10.0); - @WatchableField(MetadataIndex = 19, WatchableObjectType = WatchableObjectType.ROTATION) - protected Rotation3f leftLegRotation = new Rotation3f(-1.0, 0.0, -1.0); - @WatchableField(MetadataIndex = 20, WatchableObjectType = WatchableObjectType.ROTATION) - protected Rotation3f rightLegRotation = new Rotation3f(1.0, 0.0, 1.0); - - public ArmorStand(int entityId, UUID uuid, World world, double x, double y, double z, float yaw, float pitch) { - super(EntityType.ARMOR_STAND, entityId, uuid, world, x, y, z, yaw, pitch); - } - - public ArmorStand(UUID uuid, World world, double x, double y, double z, float yaw, float pitch) { - this(Limbo.getInstance().getNextEntityId(), uuid, world, x, y, z, yaw, pitch); - } - - public ArmorStand(World world, double x, double y, double z, float yaw, float pitch) { - this(Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), world, x, y, z, yaw, pitch); - } - - public ArmorStand(UUID uuid, Location location) { - this(Limbo.getInstance().getNextEntityId(), uuid, location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); - } - - public ArmorStand(Location location) { - this(Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); - } - public boolean isSmall() { - return small; - } + @WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x01) + protected boolean small = false; + @WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x04) + protected boolean arms = false; + @WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x08) + protected boolean noBasePlate = false; + @WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x10) + protected boolean marker = false; + @WatchableField(MetadataIndex = 15, WatchableObjectType = WatchableObjectType.ROTATION) + protected Rotation3f headRotation = new Rotation3f(0.0, 0.0, 0.0); + @WatchableField(MetadataIndex = 16, WatchableObjectType = WatchableObjectType.ROTATION) + protected Rotation3f bodyRotation = new Rotation3f(0.0, 0.0, 0.0); + @WatchableField(MetadataIndex = 17, WatchableObjectType = WatchableObjectType.ROTATION) + protected Rotation3f leftArmRotation = new Rotation3f(-10.0, 0.0, -10.0); + @WatchableField(MetadataIndex = 18, WatchableObjectType = WatchableObjectType.ROTATION) + protected Rotation3f rightArmRotation = new Rotation3f(-15.0, 0.0, 10.0); + @WatchableField(MetadataIndex = 19, WatchableObjectType = WatchableObjectType.ROTATION) + protected Rotation3f leftLegRotation = new Rotation3f(-1.0, 0.0, -1.0); + @WatchableField(MetadataIndex = 20, WatchableObjectType = WatchableObjectType.ROTATION) + protected Rotation3f rightLegRotation = new Rotation3f(1.0, 0.0, 1.0); - public void setSmall(boolean small) { - this.small = small; - } + public ArmorStand(int entityId, UUID uuid, World world, double x, double y, double z, float yaw, float pitch) { + super(EntityType.ARMOR_STAND, entityId, uuid, world, x, y, z, yaw, pitch); + } - public boolean showArms() { - return arms; - } + public ArmorStand(UUID uuid, World world, double x, double y, double z, float yaw, float pitch) { + this(Limbo.getInstance().getNextEntityId(), uuid, world, x, y, z, yaw, pitch); + } - public void setArms(boolean arms) { - this.arms = arms; - } + public ArmorStand(World world, double x, double y, double z, float yaw, float pitch) { + this(Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), world, x, y, z, yaw, pitch); + } - public boolean hasNoBasePlate() { - return noBasePlate; - } + public ArmorStand(UUID uuid, Location location) { + this(Limbo.getInstance().getNextEntityId(), uuid, location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + } - public void setNoBasePlate(boolean noBasePlate) { - this.noBasePlate = noBasePlate; - } + public ArmorStand(Location location) { + this(Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + } - public boolean isMarker() { - return marker; - } + public boolean isSmall() { + return small; + } - public void setMarker(boolean marker) { - this.marker = marker; - } + public void setSmall(boolean small) { + this.small = small; + } - public Rotation3f getHeadRotation() { - return headRotation; - } + public boolean showArms() { + return arms; + } - public void setHeadRotation(Rotation3f headRotation) { - this.headRotation = headRotation; - } + public void setArms(boolean arms) { + this.arms = arms; + } - public Rotation3f getBodyRotation() { - return bodyRotation; - } + public boolean hasNoBasePlate() { + return noBasePlate; + } - public void setBodyRotation(Rotation3f bodyRotation) { - this.bodyRotation = bodyRotation; - } + public void setNoBasePlate(boolean noBasePlate) { + this.noBasePlate = noBasePlate; + } - public Rotation3f getLeftArmRotation() { - return leftArmRotation; - } + public boolean isMarker() { + return marker; + } - public void setLeftArmRotation(Rotation3f leftArmRotation) { - this.leftArmRotation = leftArmRotation; - } + public void setMarker(boolean marker) { + this.marker = marker; + } - public Rotation3f getRightArmRotation() { - return rightArmRotation; - } + public Rotation3f getHeadRotation() { + return headRotation; + } - public void setRightArmRotation(Rotation3f rightArmRotation) { - this.rightArmRotation = rightArmRotation; - } + public void setHeadRotation(Rotation3f headRotation) { + this.headRotation = headRotation; + } - public Rotation3f getLeftLegRotation() { - return leftLegRotation; - } + public Rotation3f getBodyRotation() { + return bodyRotation; + } - public void setLeftLegRotation(Rotation3f leftLegRotation) { - this.leftLegRotation = leftLegRotation; - } + public void setBodyRotation(Rotation3f bodyRotation) { + this.bodyRotation = bodyRotation; + } - public Rotation3f getRightLegRotation() { - return rightLegRotation; - } + public Rotation3f getLeftArmRotation() { + return leftArmRotation; + } - public void setRightLegRotation(Rotation3f rightLegRotation) { - this.rightLegRotation = rightLegRotation; - } + public void setLeftArmRotation(Rotation3f leftArmRotation) { + this.leftArmRotation = leftArmRotation; + } + + public Rotation3f getRightArmRotation() { + return rightArmRotation; + } + + public void setRightArmRotation(Rotation3f rightArmRotation) { + this.rightArmRotation = rightArmRotation; + } + + public Rotation3f getLeftLegRotation() { + return leftLegRotation; + } + + public void setLeftLegRotation(Rotation3f leftLegRotation) { + this.leftLegRotation = leftLegRotation; + } + + public Rotation3f getRightLegRotation() { + return rightLegRotation; + } + + public void setRightLegRotation(Rotation3f rightLegRotation) { + this.rightLegRotation = rightLegRotation; + } } diff --git a/src/main/java/com/loohp/limbo/entity/DataWatcher.java b/src/main/java/com/loohp/limbo/entity/DataWatcher.java index 217b84c..397a778 100644 --- a/src/main/java/com/loohp/limbo/entity/DataWatcher.java +++ b/src/main/java/com/loohp/limbo/entity/DataWatcher.java @@ -11,168 +11,172 @@ import java.util.Map; import java.util.Map.Entry; public class DataWatcher { - - private Entity entity; - private Map values; - - public DataWatcher(Entity entity) { - this.entity = entity; - this.values = new HashMap<>(); - - Class clazz = entity.getClass(); - while (clazz != null) { - for (Field field : clazz.getDeclaredFields()) { - WatchableField a = field.getAnnotation(WatchableField.class); - if (a != null) { - field.setAccessible(true); - try { - values.put(field, new WatchableObject(field.get(entity), a.MetadataIndex(), a.WatchableObjectType(), a.IsOptional(), a.IsBitmask(), a.Bitmask())); - } catch (IllegalArgumentException | IllegalAccessException e) { - e.printStackTrace(); - } - } - } - clazz = clazz.getSuperclass(); - } - } - - public Entity getEntity() { - return entity; - } - - public boolean isValid() { - return entity.isValid(); - } - - public synchronized Map update() throws IllegalArgumentException, IllegalAccessException { - if (!isValid()) { - return null; - } - Map updated = new HashMap<>(); - for (Entry entry : values.entrySet()) { - Field field = entry.getKey(); - WatchableObject watchableObj = entry.getValue(); - field.setAccessible(true); - Object newValue = field.get(entity); - if ((newValue == null && watchableObj.getValue() != null) || (newValue != null && watchableObj.getValue() == null) || (newValue != null && watchableObj.getValue() != null && !newValue.equals(watchableObj.getValue()))) { - watchableObj.setValue(newValue); - updated.put(field, watchableObj); - } - } - return updated; - } - - public Map getWatchableObjects() { - return Collections.unmodifiableMap(values); - } - - public static class WatchableObject { - - private int index; - private WatchableObjectType type; - private boolean optional; - private boolean isBitmask; - private int bitmask; - - private Object value; - - public WatchableObject(Object value, int index, WatchableObjectType type, boolean optional, boolean isBitmask, int bitmask) { - this.index = index; - this.type = type; - this.optional = optional; - this.isBitmask = isBitmask; - this.bitmask = bitmask; - this.value = value; - } - - public WatchableObject(Object value, int index, WatchableObjectType type, boolean isBitmask, int bitmask) { - this(value, index, type, false, isBitmask, bitmask); - } - - public WatchableObject(Object value, int index, WatchableObjectType type, boolean optional) { - this(value, index, type, optional, false, 0x00); - } - - public WatchableObject(Object value, int index, WatchableObjectType type) { - this(value, index, type, false, false, 0x00); - } - - public Object getValue() { - return value; - } - - public void setValue(Object newValue) { - this.value = newValue; - } - public int getIndex() { - return index; - } + private final Entity entity; + private final Map values; - public WatchableObjectType getType() { - return type; - } + public DataWatcher(Entity entity) { + this.entity = entity; + this.values = new HashMap<>(); - public boolean isOptional() { - return optional; - } + Class clazz = entity.getClass(); + while (clazz != null) { + for (Field field : clazz.getDeclaredFields()) { + WatchableField a = field.getAnnotation(WatchableField.class); + if (a != null) { + field.setAccessible(true); + try { + values.put(field, new WatchableObject(field.get(entity), a.MetadataIndex(), a.WatchableObjectType(), a.IsOptional(), a.IsBitmask(), a.Bitmask())); + } catch (IllegalArgumentException | IllegalAccessException e) { + e.printStackTrace(); + } + } + } + clazz = clazz.getSuperclass(); + } + } - public boolean isBitmask() { - return isBitmask; - } + public Entity getEntity() { + return entity; + } + + public boolean isValid() { + return entity.isValid(); + } + + public synchronized Map update() throws IllegalArgumentException, IllegalAccessException { + if (!isValid()) { + return null; + } + Map updated = new HashMap<>(); + for (Entry entry : values.entrySet()) { + Field field = entry.getKey(); + WatchableObject watchableObj = entry.getValue(); + field.setAccessible(true); + Object newValue = field.get(entity); + if ((newValue == null && watchableObj.getValue() != null) || (newValue != null && watchableObj.getValue() == null) || (newValue != null && watchableObj.getValue() != null && !newValue.equals(watchableObj.getValue()))) { + watchableObj.setValue(newValue); + updated.put(field, watchableObj); + } + } + return updated; + } + + public Map getWatchableObjects() { + return Collections.unmodifiableMap(values); + } + + public enum WatchableObjectType { + BYTE(0), + VARINT(1, 17), + FLOAT(2), + STRING(3), + CHAT(4, 5), + SLOT(6), + BOOLEAN(7), + ROTATION(8), + POSITION(9, 10), + DIRECTION(11), + UUID(-1, 12), + BLOCKID(-1, 13), + NBT(14), + PARTICLE(15), + VILLAGER_DATA(16), + POSE(18); + + int typeId; + int optionalTypeId; + + WatchableObjectType(int typeId, int optionalTypeId) { + this.typeId = typeId; + this.optionalTypeId = optionalTypeId; + } + + WatchableObjectType(int typeId) { + this(typeId, -1); + } + + public int getTypeId() { + return typeId; + } + + public int getOptionalTypeId() { + return optionalTypeId; + } + } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.FIELD) + public @interface WatchableField { + int MetadataIndex(); + + WatchableObjectType WatchableObjectType(); + + boolean IsOptional() default false; + + boolean IsBitmask() default false; + + int Bitmask() default 0x00; + } + + public static class WatchableObject { + + private final int index; + private final WatchableObjectType type; + private final boolean optional; + private final boolean isBitmask; + private final int bitmask; + + private Object value; + + public WatchableObject(Object value, int index, WatchableObjectType type, boolean optional, boolean isBitmask, int bitmask) { + this.index = index; + this.type = type; + this.optional = optional; + this.isBitmask = isBitmask; + this.bitmask = bitmask; + this.value = value; + } + + public WatchableObject(Object value, int index, WatchableObjectType type, boolean isBitmask, int bitmask) { + this(value, index, type, false, isBitmask, bitmask); + } + + public WatchableObject(Object value, int index, WatchableObjectType type, boolean optional) { + this(value, index, type, optional, false, 0x00); + } + + public WatchableObject(Object value, int index, WatchableObjectType type) { + this(value, index, type, false, false, 0x00); + } + + public Object getValue() { + return value; + } + + public void setValue(Object newValue) { + this.value = newValue; + } + + public int getIndex() { + return index; + } + + public WatchableObjectType getType() { + return type; + } + + public boolean isOptional() { + return optional; + } + + public boolean isBitmask() { + return isBitmask; + } + + public int getBitmask() { + return bitmask; + } + } - public int getBitmask() { - return bitmask; - } - } - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.FIELD) - public static @interface WatchableField { - int MetadataIndex(); - WatchableObjectType WatchableObjectType(); - boolean IsOptional() default false; - boolean IsBitmask() default false; - int Bitmask() default 0x00; - } - - public static enum WatchableObjectType { - BYTE(0), - VARINT(1, 17), - FLOAT(2), - STRING(3), - CHAT(4, 5), - SLOT(6), - BOOLEAN(7), - ROTATION(8), - POSITION(9, 10), - DIRECTION(11), - UUID(-1, 12), - BLOCKID(-1, 13), - NBT(14), - PARTICLE(15), - VILLAGER_DATA(16), - POSE(18); - - int typeId; - int optionalTypeId; - - WatchableObjectType(int typeId, int optionalTypeId) { - this.typeId = typeId; - this.optionalTypeId = optionalTypeId; - } - - WatchableObjectType(int typeId) { - this(typeId, -1); - } - - public int getTypeId() { - return typeId; - } - - public int getOptionalTypeId() { - return optionalTypeId; - } - } - } diff --git a/src/main/java/com/loohp/limbo/entity/Entity.java b/src/main/java/com/loohp/limbo/entity/Entity.java index 66c9a92..9883144 100644 --- a/src/main/java/com/loohp/limbo/entity/Entity.java +++ b/src/main/java/com/loohp/limbo/entity/Entity.java @@ -1,283 +1,280 @@ package com.loohp.limbo.entity; -import java.util.UUID; - import com.loohp.limbo.Limbo; import com.loohp.limbo.entity.DataWatcher.WatchableField; import com.loohp.limbo.entity.DataWatcher.WatchableObjectType; import com.loohp.limbo.location.Location; import com.loohp.limbo.world.World; - import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.TextComponent; +import java.util.UUID; + public abstract class Entity { - - @WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x01) - protected boolean onFire = false; - @WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x02) - protected boolean crouching = false; - @WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x04) - protected boolean unused = false; - @WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x08) - protected boolean sprinting = false; - @WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x10) - protected boolean swimming = false; - @WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x20) - protected boolean invisible = false; - @WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x40) - protected boolean glowing = false; - @WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x80) - protected boolean elytraFlying = false; - @WatchableField(MetadataIndex = 1, WatchableObjectType = WatchableObjectType.VARINT) - protected int air = 300; - @WatchableField(MetadataIndex = 2, WatchableObjectType = WatchableObjectType.CHAT, IsOptional = true) - protected BaseComponent[] customName = null; - @WatchableField(MetadataIndex = 3, WatchableObjectType = WatchableObjectType.BOOLEAN) - protected boolean customNameVisible = false; - @WatchableField(MetadataIndex = 4, WatchableObjectType = WatchableObjectType.BOOLEAN) - protected boolean silent = false; - @WatchableField(MetadataIndex = 5, WatchableObjectType = WatchableObjectType.BOOLEAN) - protected boolean noGravity = false; - @WatchableField(MetadataIndex = 6, WatchableObjectType = WatchableObjectType.POSE) - protected Pose pose = Pose.STANDING; - - protected final EntityType type; - - protected int entityId; - protected UUID uuid; - protected World world; - protected double x; - protected double y; - protected double z; - protected float yaw; - protected float pitch; - - public Entity(EntityType type, int entityId, UUID uuid, World world, double x, double y, double z, float yaw, float pitch) { - this.type = type; - this.entityId = entityId; - this.uuid = uuid; - this.world = world; - this.x = x; - this.y = y; - this.z = z; - this.yaw = yaw; - this.pitch = pitch; - } - - public Entity(EntityType type, UUID uuid, World world, double x, double y, double z, float yaw, float pitch) { - this(type, Limbo.getInstance().getNextEntityId(), uuid, world, x, y, z, yaw, pitch); - } - - public Entity(EntityType type, World world, double x, double y, double z, float yaw, float pitch) { - this(type, Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), world, x, y, z, yaw, pitch); - } - - public Entity(EntityType type, UUID uuid, Location location) { - this(type, Limbo.getInstance().getNextEntityId(), uuid, location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); - } - - public Entity(EntityType type, Location location) { - this(type, Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); - } - - public EntityType getType() { - return type; - } - - public Location getLocation() { - return new Location(world, x, y, z, yaw, pitch); - } - - public void teleport(Location location) { - this.world = location.getWorld(); - this.x = location.getX(); - this.y = location.getY(); - this.z = location.getZ(); - this.yaw = location.getYaw(); - this.pitch = location.getPitch(); - } - - public BaseComponent[] getCustomName() { - return customName; - } - - public void setCustomName(String name) { - this.customName = name == null ? null : new BaseComponent[] {new TextComponent(name)}; - } - - public void setCustomName(BaseComponent component) { - this.customName = component == null ? null : new BaseComponent[] {component}; - } - - public void setCustomName(BaseComponent[] components) { - this.customName = components; - } - public boolean isOnFire() { - return onFire; - } + protected final EntityType type; + @WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x01) + protected boolean onFire = false; + @WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x02) + protected boolean crouching = false; + @WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x04) + protected boolean unused = false; + @WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x08) + protected boolean sprinting = false; + @WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x10) + protected boolean swimming = false; + @WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x20) + protected boolean invisible = false; + @WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x40) + protected boolean glowing = false; + @WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x80) + protected boolean elytraFlying = false; + @WatchableField(MetadataIndex = 1, WatchableObjectType = WatchableObjectType.VARINT) + protected int air = 300; + @WatchableField(MetadataIndex = 2, WatchableObjectType = WatchableObjectType.CHAT, IsOptional = true) + protected BaseComponent[] customName = null; + @WatchableField(MetadataIndex = 3, WatchableObjectType = WatchableObjectType.BOOLEAN) + protected boolean customNameVisible = false; + @WatchableField(MetadataIndex = 4, WatchableObjectType = WatchableObjectType.BOOLEAN) + protected boolean silent = false; + @WatchableField(MetadataIndex = 5, WatchableObjectType = WatchableObjectType.BOOLEAN) + protected boolean noGravity = false; + @WatchableField(MetadataIndex = 6, WatchableObjectType = WatchableObjectType.POSE) + protected Pose pose = Pose.STANDING; + protected int entityId; + protected UUID uuid; + protected World world; + protected double x; + protected double y; + protected double z; + protected float yaw; + protected float pitch; - public void setOnFire(boolean onFire) { - this.onFire = onFire; - } + public Entity(EntityType type, int entityId, UUID uuid, World world, double x, double y, double z, float yaw, float pitch) { + this.type = type; + this.entityId = entityId; + this.uuid = uuid; + this.world = world; + this.x = x; + this.y = y; + this.z = z; + this.yaw = yaw; + this.pitch = pitch; + } - public boolean isCrouching() { - return crouching; - } + public Entity(EntityType type, UUID uuid, World world, double x, double y, double z, float yaw, float pitch) { + this(type, Limbo.getInstance().getNextEntityId(), uuid, world, x, y, z, yaw, pitch); + } - public void setCrouching(boolean crouching) { - this.crouching = crouching; - } + public Entity(EntityType type, World world, double x, double y, double z, float yaw, float pitch) { + this(type, Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), world, x, y, z, yaw, pitch); + } - public boolean isSprinting() { - return sprinting; - } + public Entity(EntityType type, UUID uuid, Location location) { + this(type, Limbo.getInstance().getNextEntityId(), uuid, location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + } - public void setSprinting(boolean sprinting) { - this.sprinting = sprinting; - } + public Entity(EntityType type, Location location) { + this(type, Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + } - public boolean isSwimming() { - return swimming; - } + public EntityType getType() { + return type; + } - public void setSwimming(boolean swimming) { - this.swimming = swimming; - } + public Location getLocation() { + return new Location(world, x, y, z, yaw, pitch); + } - public boolean isInvisible() { - return invisible; - } + public void teleport(Location location) { + this.world = location.getWorld(); + this.x = location.getX(); + this.y = location.getY(); + this.z = location.getZ(); + this.yaw = location.getYaw(); + this.pitch = location.getPitch(); + } - public void setInvisible(boolean invisible) { - this.invisible = invisible; - } + public BaseComponent[] getCustomName() { + return customName; + } - public boolean isGlowing() { - return glowing; - } + public void setCustomName(String name) { + this.customName = name == null ? null : new BaseComponent[]{new TextComponent(name)}; + } - public void setGlowing(boolean glowing) { - this.glowing = glowing; - } + public void setCustomName(BaseComponent component) { + this.customName = component == null ? null : new BaseComponent[]{component}; + } - public boolean isElytraFlying() { - return elytraFlying; - } + public void setCustomName(BaseComponent[] components) { + this.customName = components; + } - public void setElytraFlying(boolean elytraFlying) { - this.elytraFlying = elytraFlying; - } + public boolean isOnFire() { + return onFire; + } - public int getAir() { - return air; - } + public void setOnFire(boolean onFire) { + this.onFire = onFire; + } - public void setAir(int air) { - this.air = air; - } + public boolean isCrouching() { + return crouching; + } - public boolean isCustomNameVisible() { - return customNameVisible; - } + public void setCrouching(boolean crouching) { + this.crouching = crouching; + } - public void setCustomNameVisible(boolean customNameVisible) { - this.customNameVisible = customNameVisible; - } + public boolean isSprinting() { + return sprinting; + } - public boolean isSilent() { - return silent; - } + public void setSprinting(boolean sprinting) { + this.sprinting = sprinting; + } - public void setSilent(boolean silent) { - this.silent = silent; - } + public boolean isSwimming() { + return swimming; + } - public boolean hasGravity() { - return !noGravity; - } + public void setSwimming(boolean swimming) { + this.swimming = swimming; + } - public void setGravity(boolean gravity) { - this.noGravity = !gravity; - } + public boolean isInvisible() { + return invisible; + } - public Pose getPose() { - return pose; - } + public void setInvisible(boolean invisible) { + this.invisible = invisible; + } - public void setPose(Pose pose) { - this.pose = pose; - } + public boolean isGlowing() { + return glowing; + } - public World getWorld() { - return world; - } + public void setGlowing(boolean glowing) { + this.glowing = glowing; + } - public void setWorld(World world) { - this.world = world; - } + public boolean isElytraFlying() { + return elytraFlying; + } - public double getX() { - return x; - } + public void setElytraFlying(boolean elytraFlying) { + this.elytraFlying = elytraFlying; + } - public void setX(double x) { - this.x = x; - } + public int getAir() { + return air; + } - public double getY() { - return y; - } + public void setAir(int air) { + this.air = air; + } - public void setY(double y) { - this.y = y; - } + public boolean isCustomNameVisible() { + return customNameVisible; + } - public double getZ() { - return z; - } + public void setCustomNameVisible(boolean customNameVisible) { + this.customNameVisible = customNameVisible; + } - public void setZ(double z) { - this.z = z; - } + public boolean isSilent() { + return silent; + } - public float getYaw() { - return yaw; - } + public void setSilent(boolean silent) { + this.silent = silent; + } - public void setYaw(float yaw) { - this.yaw = yaw; - } + public boolean hasGravity() { + return !noGravity; + } - public float getPitch() { - return pitch; - } + public void setGravity(boolean gravity) { + this.noGravity = !gravity; + } - public void setPitch(float pitch) { - this.pitch = pitch; - } + public Pose getPose() { + return pose; + } - public int getEntityId() { - return entityId; - } + public void setPose(Pose pose) { + this.pose = pose; + } - public UUID getUniqueId() { - return uuid; - } - - public boolean isValid() { - return world.getEntities().contains(this); - } - - @SuppressWarnings("deprecation") - public void remove() { - Limbo.getInstance().getUnsafe().removeEntity(world, this); - } - - @SuppressWarnings("deprecation") - public DataWatcher getDataWatcher() { - return Limbo.getInstance().getUnsafe().getDataWatcher(world, this); - } + public World getWorld() { + return world; + } + + public void setWorld(World world) { + this.world = world; + } + + public double getX() { + return x; + } + + public void setX(double x) { + this.x = x; + } + + public double getY() { + return y; + } + + public void setY(double y) { + this.y = y; + } + + public double getZ() { + return z; + } + + public void setZ(double z) { + this.z = z; + } + + public float getYaw() { + return yaw; + } + + public void setYaw(float yaw) { + this.yaw = yaw; + } + + public float getPitch() { + return pitch; + } + + public void setPitch(float pitch) { + this.pitch = pitch; + } + + public int getEntityId() { + return entityId; + } + + public UUID getUniqueId() { + return uuid; + } + + public boolean isValid() { + return world.getEntities().contains(this); + } + + @SuppressWarnings("deprecation") + public void remove() { + Limbo.getInstance().getUnsafe().removeEntity(world, this); + } + + @SuppressWarnings("deprecation") + public DataWatcher getDataWatcher() { + return Limbo.getInstance().getUnsafe().getDataWatcher(world, this); + } } diff --git a/src/main/java/com/loohp/limbo/entity/EntityType.java b/src/main/java/com/loohp/limbo/entity/EntityType.java index 7dea099..21a2f01 100644 --- a/src/main/java/com/loohp/limbo/entity/EntityType.java +++ b/src/main/java/com/loohp/limbo/entity/EntityType.java @@ -1,13 +1,13 @@ package com.loohp.limbo.entity; -import java.util.HashMap; -import java.util.Map; - import com.loohp.limbo.location.Location; import com.loohp.limbo.player.Player; import com.loohp.limbo.utils.NamespacedKey; import com.loohp.limbo.world.World; +import java.util.HashMap; +import java.util.Map; + public enum EntityType { // These strings MUST match the strings in nms.EntityTypes and are case sensitive. @@ -270,13 +270,6 @@ public enum EntityType { */ UNKNOWN(null, null, -1, false); - private final String name; - private final Class clazz; - private final short typeId; - private final boolean independent; - private final boolean living; - private final NamespacedKey key; - private static final Map NAME_MAP = new HashMap<>(); private static final Map ID_MAP = new HashMap<>(); @@ -308,11 +301,18 @@ public enum EntityType { */ } - private EntityType(String name, Class clazz, int typeId) { + private final String name; + private final Class clazz; + private final short typeId; + private final boolean independent; + private final boolean living; + private final NamespacedKey key; + + EntityType(String name, Class clazz, int typeId) { this(name, clazz, typeId, true); } - private EntityType(String name, Class clazz, int typeId, boolean independent) { + EntityType(String name, Class clazz, int typeId, boolean independent) { this.name = name; this.clazz = clazz; this.typeId = (short) typeId; @@ -321,34 +321,6 @@ public enum EntityType { this.key = (name == null) ? null : NamespacedKey.minecraft(name); } - /** - * Gets the entity type name. - * - * @return the entity type's name - * @deprecated Magic value - */ - @Deprecated - public String getName() { - return name; - } - - public NamespacedKey getKey() { - return key; - } - - public Class getEntityClass() { - return clazz; - } - - /** - * Gets the entity network type id. - * - * @return the network type id - */ - public short getTypeId() { - return typeId; - } - /** * Gets an entity type from its name. * @@ -379,6 +351,34 @@ public enum EntityType { return ID_MAP.get((short) id); } + /** + * Gets the entity type name. + * + * @return the entity type's name + * @deprecated Magic value + */ + @Deprecated + public String getName() { + return name; + } + + public NamespacedKey getKey() { + return key; + } + + public Class getEntityClass() { + return clazz; + } + + /** + * Gets the entity network type id. + * + * @return the network type id + */ + public short getTypeId() { + return typeId; + } + /** * Some entities cannot be spawned using {@link * World#spawnEntity(Location, EntityType)} or {@link diff --git a/src/main/java/com/loohp/limbo/entity/LivingEntity.java b/src/main/java/com/loohp/limbo/entity/LivingEntity.java index 0b3c620..a0eb7b3 100644 --- a/src/main/java/com/loohp/limbo/entity/LivingEntity.java +++ b/src/main/java/com/loohp/limbo/entity/LivingEntity.java @@ -1,7 +1,5 @@ package com.loohp.limbo.entity; -import java.util.UUID; - import com.loohp.limbo.Limbo; import com.loohp.limbo.entity.DataWatcher.WatchableField; import com.loohp.limbo.entity.DataWatcher.WatchableObjectType; @@ -10,123 +8,125 @@ import com.loohp.limbo.location.Location; import com.loohp.limbo.world.BlockPosition; import com.loohp.limbo.world.World; +import java.util.UUID; + public abstract class LivingEntity extends Entity { - - @WatchableField(MetadataIndex = 7, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x01) - protected boolean handActive = false; - @WatchableField(MetadataIndex = 7, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x02) - protected boolean activeHand = false; //false = main hand, true = off hand - @WatchableField(MetadataIndex = 7, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x04) - protected boolean inRiptideSpinAttack = false; - @WatchableField(MetadataIndex = 8, WatchableObjectType = WatchableObjectType.FLOAT) - protected float health = 1.0F; - @WatchableField(MetadataIndex = 9, WatchableObjectType = WatchableObjectType.VARINT) - protected int potionEffectColor = 0; - @WatchableField(MetadataIndex = 10, WatchableObjectType = WatchableObjectType.BOOLEAN) - protected boolean potionEffectAmbient = false; - @WatchableField(MetadataIndex = 11, WatchableObjectType = WatchableObjectType.VARINT) - protected int arrowsInEntity = 0; - @WatchableField(MetadataIndex = 12, WatchableObjectType = WatchableObjectType.VARINT) - protected int absorption = 0; - @WatchableField(MetadataIndex = 13, WatchableObjectType = WatchableObjectType.POSITION, IsOptional = true) - protected BlockPosition sleepingLocation = null; - public LivingEntity(EntityType type, int entityId, UUID uuid, World world, double x, double y, double z, float yaw, float pitch) { - super(type, entityId, uuid, world, x, y, z, yaw, pitch); - } - - public LivingEntity(EntityType type, UUID uuid, World world, double x, double y, double z, float yaw, float pitch) { - this(type, Limbo.getInstance().getNextEntityId(), uuid, world, x, y, z, yaw, pitch); - } - - public LivingEntity(EntityType type, World world, double x, double y, double z, float yaw, float pitch) { - this(type, Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), world, x, y, z, yaw, pitch); - } - - public LivingEntity(EntityType type, UUID uuid, Location location) { - this(type, Limbo.getInstance().getNextEntityId(), uuid, location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); - } - - public LivingEntity(EntityType type, Location location) { - this(type, Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); - } + @WatchableField(MetadataIndex = 7, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x01) + protected boolean handActive = false; + @WatchableField(MetadataIndex = 7, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x02) + protected boolean activeHand = false; //false = main hand, true = off hand + @WatchableField(MetadataIndex = 7, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x04) + protected boolean inRiptideSpinAttack = false; + @WatchableField(MetadataIndex = 8, WatchableObjectType = WatchableObjectType.FLOAT) + protected float health = 1.0F; + @WatchableField(MetadataIndex = 9, WatchableObjectType = WatchableObjectType.VARINT) + protected int potionEffectColor = 0; + @WatchableField(MetadataIndex = 10, WatchableObjectType = WatchableObjectType.BOOLEAN) + protected boolean potionEffectAmbient = false; + @WatchableField(MetadataIndex = 11, WatchableObjectType = WatchableObjectType.VARINT) + protected int arrowsInEntity = 0; + @WatchableField(MetadataIndex = 12, WatchableObjectType = WatchableObjectType.VARINT) + protected int absorption = 0; + @WatchableField(MetadataIndex = 13, WatchableObjectType = WatchableObjectType.POSITION, IsOptional = true) + protected BlockPosition sleepingLocation = null; - public boolean isHandActive() { - return handActive; - } + public LivingEntity(EntityType type, int entityId, UUID uuid, World world, double x, double y, double z, float yaw, float pitch) { + super(type, entityId, uuid, world, x, y, z, yaw, pitch); + } - public void setHandActive(boolean handActive) { - this.handActive = handActive; - } + public LivingEntity(EntityType type, UUID uuid, World world, double x, double y, double z, float yaw, float pitch) { + this(type, Limbo.getInstance().getNextEntityId(), uuid, world, x, y, z, yaw, pitch); + } - public EquipmentSlot getActiveHand() { - return activeHand ? EquipmentSlot.OFFHAND : EquipmentSlot.MAINHAND; - } + public LivingEntity(EntityType type, World world, double x, double y, double z, float yaw, float pitch) { + this(type, Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), world, x, y, z, yaw, pitch); + } - public void setActiveHand(EquipmentSlot activeHand) { - if (activeHand.equals(EquipmentSlot.MAINHAND)) { - this.activeHand = false; - } else if (activeHand.equals(EquipmentSlot.OFFHAND)) { - this.activeHand = true; - } else { - throw new IllegalArgumentException("Invalid EquipmentSlot " + activeHand.toString()); - } - } + public LivingEntity(EntityType type, UUID uuid, Location location) { + this(type, Limbo.getInstance().getNextEntityId(), uuid, location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + } - public boolean isInRiptideSpinAttack() { - return inRiptideSpinAttack; - } + public LivingEntity(EntityType type, Location location) { + this(type, Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + } - public void setInRiptideSpinAttack(boolean inRiptideSpinAttack) { - this.inRiptideSpinAttack = inRiptideSpinAttack; - } + public boolean isHandActive() { + return handActive; + } - public float getHealth() { - return health; - } + public void setHandActive(boolean handActive) { + this.handActive = handActive; + } - public void setHealth(float health) { - this.health = health; - } + public EquipmentSlot getActiveHand() { + return activeHand ? EquipmentSlot.OFFHAND : EquipmentSlot.MAINHAND; + } - public int getPotionEffectColor() { - return potionEffectColor; - } + public void setActiveHand(EquipmentSlot activeHand) { + if (activeHand.equals(EquipmentSlot.MAINHAND)) { + this.activeHand = false; + } else if (activeHand.equals(EquipmentSlot.OFFHAND)) { + this.activeHand = true; + } else { + throw new IllegalArgumentException("Invalid EquipmentSlot " + activeHand); + } + } - public void setPotionEffectColor(int potionEffectColor) { - this.potionEffectColor = potionEffectColor; - } + public boolean isInRiptideSpinAttack() { + return inRiptideSpinAttack; + } - public boolean isPotionEffectAmbient() { - return potionEffectAmbient; - } + public void setInRiptideSpinAttack(boolean inRiptideSpinAttack) { + this.inRiptideSpinAttack = inRiptideSpinAttack; + } - public void setPotionEffectAmbient(boolean potionEffectAmbient) { - this.potionEffectAmbient = potionEffectAmbient; - } + public float getHealth() { + return health; + } - public int getArrowsInEntity() { - return arrowsInEntity; - } + public void setHealth(float health) { + this.health = health; + } - public void setArrowsInEntity(int arrowsInEntity) { - this.arrowsInEntity = arrowsInEntity; - } + public int getPotionEffectColor() { + return potionEffectColor; + } - public int getAbsorption() { - return absorption; - } + public void setPotionEffectColor(int potionEffectColor) { + this.potionEffectColor = potionEffectColor; + } - public void setAbsorption(int absorption) { - this.absorption = absorption; - } + public boolean isPotionEffectAmbient() { + return potionEffectAmbient; + } - public BlockPosition getSleepingLocation() { - return sleepingLocation; - } + public void setPotionEffectAmbient(boolean potionEffectAmbient) { + this.potionEffectAmbient = potionEffectAmbient; + } - public void setSleepingLocation(BlockPosition sleepingLocation) { - this.sleepingLocation = sleepingLocation; - } + public int getArrowsInEntity() { + return arrowsInEntity; + } + + public void setArrowsInEntity(int arrowsInEntity) { + this.arrowsInEntity = arrowsInEntity; + } + + public int getAbsorption() { + return absorption; + } + + public void setAbsorption(int absorption) { + this.absorption = absorption; + } + + public BlockPosition getSleepingLocation() { + return sleepingLocation; + } + + public void setSleepingLocation(BlockPosition sleepingLocation) { + this.sleepingLocation = sleepingLocation; + } } diff --git a/src/main/java/com/loohp/limbo/entity/Pose.java b/src/main/java/com/loohp/limbo/entity/Pose.java index c020e21..0bec91e 100644 --- a/src/main/java/com/loohp/limbo/entity/Pose.java +++ b/src/main/java/com/loohp/limbo/entity/Pose.java @@ -1,34 +1,34 @@ package com.loohp.limbo.entity; public enum Pose { - - STANDING(0), - FALL_FLYING(1), - SLEEPING(2), - SWIMMING(3), - SPIN_ATTACK(4), - SNEAKING(5), - DYING(6); - - private static final Pose[] VALUES = values(); - - private int id; - - Pose(int id) { - this.id = id; - } - - public int getId() { - return id; - } - - public static Pose fromId(int id) { - for (Pose pose : VALUES) { - if (id == pose.id) { - return pose; - } - } - return null; - } + + STANDING(0), + FALL_FLYING(1), + SLEEPING(2), + SWIMMING(3), + SPIN_ATTACK(4), + SNEAKING(5), + DYING(6); + + private static final Pose[] VALUES = values(); + + private final int id; + + Pose(int id) { + this.id = id; + } + + public static Pose fromId(int id) { + for (Pose pose : VALUES) { + if (id == pose.id) { + return pose; + } + } + return null; + } + + public int getId() { + return id; + } } diff --git a/src/main/java/com/loohp/limbo/events/Cancellable.java b/src/main/java/com/loohp/limbo/events/Cancellable.java index 7f0c192..f061d26 100644 --- a/src/main/java/com/loohp/limbo/events/Cancellable.java +++ b/src/main/java/com/loohp/limbo/events/Cancellable.java @@ -1,9 +1,9 @@ package com.loohp.limbo.events; public interface Cancellable { - - public void setCancelled(boolean cancelled); - - public boolean isCancelled(); + + boolean isCancelled(); + + void setCancelled(boolean cancelled); } diff --git a/src/main/java/com/loohp/limbo/events/EventHandler.java b/src/main/java/com/loohp/limbo/events/EventHandler.java index 126f257..30cba30 100644 --- a/src/main/java/com/loohp/limbo/events/EventHandler.java +++ b/src/main/java/com/loohp/limbo/events/EventHandler.java @@ -1,14 +1,10 @@ package com.loohp.limbo.events; -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +import java.lang.annotation.*; @Documented @Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface EventHandler { - EventPriority priority() default EventPriority.NORMAL; +@Retention(RetentionPolicy.RUNTIME) +public @interface EventHandler { + EventPriority priority() default EventPriority.NORMAL; } \ No newline at end of file diff --git a/src/main/java/com/loohp/limbo/events/EventPriority.java b/src/main/java/com/loohp/limbo/events/EventPriority.java index 89fc3f6..17fcfdc 100644 --- a/src/main/java/com/loohp/limbo/events/EventPriority.java +++ b/src/main/java/com/loohp/limbo/events/EventPriority.java @@ -1,37 +1,37 @@ package com.loohp.limbo.events; public enum EventPriority { - LOWEST(0), - LOW(1), - NORMAL(2), - HIGH(3), - HIGHEST(4), - MONITOR(5); - - int order; - - EventPriority(int order) { - this.order = order; - } - - public int getOrder() { - return order; - } - - public static EventPriority getByOrder(int order) { - for (EventPriority each : EventPriority.values()) { - if (each.getOrder() == order) { - return each; - } - } - return null; - } - - public static EventPriority[] getPrioritiesInOrder() { - EventPriority[] array = new EventPriority[EventPriority.values().length]; - for (int i = 0; i < array.length; i++) { - array[i] = EventPriority.getByOrder(i); - } - return array; - } + LOWEST(0), + LOW(1), + NORMAL(2), + HIGH(3), + HIGHEST(4), + MONITOR(5); + + int order; + + EventPriority(int order) { + this.order = order; + } + + public static EventPriority getByOrder(int order) { + for (EventPriority each : EventPriority.values()) { + if (each.getOrder() == order) { + return each; + } + } + return null; + } + + public static EventPriority[] getPrioritiesInOrder() { + EventPriority[] array = new EventPriority[EventPriority.values().length]; + for (int i = 0; i < array.length; i++) { + array[i] = EventPriority.getByOrder(i); + } + return array; + } + + public int getOrder() { + return order; + } } \ No newline at end of file diff --git a/src/main/java/com/loohp/limbo/events/EventsManager.java b/src/main/java/com/loohp/limbo/events/EventsManager.java index 1db524f..0ea7f34 100644 --- a/src/main/java/com/loohp/limbo/events/EventsManager.java +++ b/src/main/java/com/loohp/limbo/events/EventsManager.java @@ -1,58 +1,58 @@ package com.loohp.limbo.events; +import com.loohp.limbo.plugins.LimboPlugin; + import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; -import com.loohp.limbo.plugins.LimboPlugin; - public class EventsManager { - - private List listeners; - - public EventsManager() { - listeners = new ArrayList<>(); - } - - public T callEvent(T event) { - for (EventPriority priority : EventPriority.getPrioritiesInOrder()) { - for (ListenerPair entry : listeners) { - Listener listener = entry.listener; - for (Method method : listener.getClass().getMethods()) { - if (method.isAnnotationPresent(EventHandler.class)) { - if (method.getAnnotation(EventHandler.class).priority().equals(priority)) { - if (method.getParameterCount() == 1 && method.getParameterTypes()[0].equals(event.getClass())) { - try { - method.invoke(listener, event); - } catch (Exception e) { - System.err.println("Error while passing " + event.getClass().getCanonicalName() + " to the plugin \"" + entry.plugin.getName() + "\""); - e.printStackTrace(); - } - } - } - } - } - } - } - return event; - } - - public void registerEvents(LimboPlugin plugin, Listener listener) { - listeners.add(new ListenerPair(plugin, listener)); - } - - public void unregisterAllListeners(LimboPlugin plugin) { - listeners.removeIf(each -> each.plugin.equals(plugin)); - } - - protected static class ListenerPair { - public LimboPlugin plugin; - public Listener listener; - - public ListenerPair(LimboPlugin plugin, Listener listener) { - this.plugin = plugin; - this.listener = listener; - } - } + + private final List listeners; + + public EventsManager() { + listeners = new ArrayList<>(); + } + + public T callEvent(T event) { + for (EventPriority priority : EventPriority.getPrioritiesInOrder()) { + for (ListenerPair entry : listeners) { + Listener listener = entry.listener; + for (Method method : listener.getClass().getMethods()) { + if (method.isAnnotationPresent(EventHandler.class)) { + if (method.getAnnotation(EventHandler.class).priority().equals(priority)) { + if (method.getParameterCount() == 1 && method.getParameterTypes()[0].equals(event.getClass())) { + try { + method.invoke(listener, event); + } catch (Exception e) { + System.err.println("Error while passing " + event.getClass().getCanonicalName() + " to the plugin \"" + entry.plugin.getName() + "\""); + e.printStackTrace(); + } + } + } + } + } + } + } + return event; + } + + public void registerEvents(LimboPlugin plugin, Listener listener) { + listeners.add(new ListenerPair(plugin, listener)); + } + + public void unregisterAllListeners(LimboPlugin plugin) { + listeners.removeIf(each -> each.plugin.equals(plugin)); + } + + protected static class ListenerPair { + public LimboPlugin plugin; + public Listener listener; + + public ListenerPair(LimboPlugin plugin, Listener listener) { + this.plugin = plugin; + this.listener = listener; + } + } } diff --git a/src/main/java/com/loohp/limbo/events/player/PlayerChatEvent.java b/src/main/java/com/loohp/limbo/events/player/PlayerChatEvent.java index 1684620..12e937b 100644 --- a/src/main/java/com/loohp/limbo/events/player/PlayerChatEvent.java +++ b/src/main/java/com/loohp/limbo/events/player/PlayerChatEvent.java @@ -5,41 +5,41 @@ import com.loohp.limbo.player.Player; public class PlayerChatEvent extends PlayerEvent implements Cancellable { - private String prefix; - private String message; - private boolean cancelled; + private String prefix; + private String message; + private boolean cancelled; - public PlayerChatEvent(Player player, String prefix, String message, boolean cancelled) { - super(player); - this.prefix = prefix; - this.message = message; - this.cancelled = cancelled; - } + public PlayerChatEvent(Player player, String prefix, String message, boolean cancelled) { + super(player); + this.prefix = prefix; + this.message = message; + this.cancelled = cancelled; + } - public String getPrefix() { - return prefix; - } + public String getPrefix() { + return prefix; + } - public void setPrefix(String prefix) { - this.prefix = prefix; - } + public void setPrefix(String prefix) { + this.prefix = prefix; + } - public String getMessage() { - return message; - } + public String getMessage() { + return message; + } - public void setMessage(String message) { - this.message = message; - } + public void setMessage(String message) { + this.message = message; + } - @Override - public void setCancelled(boolean cancelled) { - this.cancelled = cancelled; - } + @Override + public boolean isCancelled() { + return cancelled; + } - @Override - public boolean isCancelled() { - return cancelled; - } + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } } diff --git a/src/main/java/com/loohp/limbo/events/player/PlayerEvent.java b/src/main/java/com/loohp/limbo/events/player/PlayerEvent.java index 47b2eb6..924fdad 100644 --- a/src/main/java/com/loohp/limbo/events/player/PlayerEvent.java +++ b/src/main/java/com/loohp/limbo/events/player/PlayerEvent.java @@ -4,15 +4,15 @@ import com.loohp.limbo.events.Event; import com.loohp.limbo.player.Player; public class PlayerEvent extends Event { - - private Player player; - - public PlayerEvent(Player player) { - this.player = player; - } - - public Player getPlayer() { - return player; - } + + private final Player player; + + public PlayerEvent(Player player) { + this.player = player; + } + + public Player getPlayer() { + return player; + } } diff --git a/src/main/java/com/loohp/limbo/events/player/PlayerJoinEvent.java b/src/main/java/com/loohp/limbo/events/player/PlayerJoinEvent.java index 0178f32..606ae85 100644 --- a/src/main/java/com/loohp/limbo/events/player/PlayerJoinEvent.java +++ b/src/main/java/com/loohp/limbo/events/player/PlayerJoinEvent.java @@ -5,18 +5,18 @@ import com.loohp.limbo.player.Player; public class PlayerJoinEvent extends PlayerEvent { - private Location spawnLocation; + private Location spawnLocation; - public PlayerJoinEvent(Player player, Location spawnLoc) { - super(player); - spawnLocation = spawnLoc; - } + public PlayerJoinEvent(Player player, Location spawnLoc) { + super(player); + spawnLocation = spawnLoc; + } - public Location getSpawnLocation() { - return spawnLocation; - } + public Location getSpawnLocation() { + return spawnLocation; + } - public void setSpawnLocation(Location spawnLocation) { - this.spawnLocation = spawnLocation; - } + public void setSpawnLocation(Location spawnLocation) { + this.spawnLocation = spawnLocation; + } } diff --git a/src/main/java/com/loohp/limbo/events/player/PlayerLoginEvent.java b/src/main/java/com/loohp/limbo/events/player/PlayerLoginEvent.java index e4845ce..9c7fc44 100644 --- a/src/main/java/com/loohp/limbo/events/player/PlayerLoginEvent.java +++ b/src/main/java/com/loohp/limbo/events/player/PlayerLoginEvent.java @@ -3,41 +3,40 @@ package com.loohp.limbo.events.player; import com.loohp.limbo.events.Cancellable; import com.loohp.limbo.events.Event; import com.loohp.limbo.server.ClientConnection; - import net.md_5.bungee.api.chat.BaseComponent; public class PlayerLoginEvent extends Event implements Cancellable { - - private ClientConnection connection; - private boolean cancelled; - private BaseComponent[] cancelReason; - - public PlayerLoginEvent(ClientConnection connection, boolean cancelled, BaseComponent... cancelReason) { - this.connection = connection; - this.cancelled = cancelled; - this.cancelReason = cancelReason; - } - public ClientConnection getConnection() { - return connection; - } + private final ClientConnection connection; + private boolean cancelled; + private BaseComponent[] cancelReason; - public BaseComponent[] getCancelReason() { - return cancelReason; - } + public PlayerLoginEvent(ClientConnection connection, boolean cancelled, BaseComponent... cancelReason) { + this.connection = connection; + this.cancelled = cancelled; + this.cancelReason = cancelReason; + } - public void setCancelReason(BaseComponent... cancelReason) { - this.cancelReason = cancelReason; - } + public ClientConnection getConnection() { + return connection; + } - @Override - public void setCancelled(boolean cancelled) { - this.cancelled = cancelled; - } + public BaseComponent[] getCancelReason() { + return cancelReason; + } - @Override - public boolean isCancelled() { - return cancelled; - } + public void setCancelReason(BaseComponent... cancelReason) { + this.cancelReason = cancelReason; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } } diff --git a/src/main/java/com/loohp/limbo/events/player/PlayerQuitEvent.java b/src/main/java/com/loohp/limbo/events/player/PlayerQuitEvent.java index 5966a11..1d7296f 100644 --- a/src/main/java/com/loohp/limbo/events/player/PlayerQuitEvent.java +++ b/src/main/java/com/loohp/limbo/events/player/PlayerQuitEvent.java @@ -3,9 +3,9 @@ package com.loohp.limbo.events.player; import com.loohp.limbo.player.Player; public class PlayerQuitEvent extends PlayerEvent { - - public PlayerQuitEvent(Player player) { - super(player); - } + + public PlayerQuitEvent(Player player) { + super(player); + } } diff --git a/src/main/java/com/loohp/limbo/events/player/PlayerSelectedSlotChangeEvent.java b/src/main/java/com/loohp/limbo/events/player/PlayerSelectedSlotChangeEvent.java index 431fccd..4036bf5 100644 --- a/src/main/java/com/loohp/limbo/events/player/PlayerSelectedSlotChangeEvent.java +++ b/src/main/java/com/loohp/limbo/events/player/PlayerSelectedSlotChangeEvent.java @@ -14,13 +14,13 @@ public class PlayerSelectedSlotChangeEvent extends PlayerEvent implements Cancel } @Override - public void setCancelled(boolean cancelled) { - this.cancel = cancelled; + public boolean isCancelled() { + return cancel; } @Override - public boolean isCancelled() { - return cancel; + public void setCancelled(boolean cancelled) { + this.cancel = cancelled; } public byte getSlot() { diff --git a/src/main/java/com/loohp/limbo/events/player/PlayerTeleportEvent.java b/src/main/java/com/loohp/limbo/events/player/PlayerTeleportEvent.java index c466310..eb744ff 100644 --- a/src/main/java/com/loohp/limbo/events/player/PlayerTeleportEvent.java +++ b/src/main/java/com/loohp/limbo/events/player/PlayerTeleportEvent.java @@ -5,8 +5,8 @@ import com.loohp.limbo.player.Player; public class PlayerTeleportEvent extends PlayerMoveEvent { - public PlayerTeleportEvent(Player player, Location from, Location to) { - super(player, from, to); - } + public PlayerTeleportEvent(Player player, Location from, Location to) { + super(player, from, to); + } } diff --git a/src/main/java/com/loohp/limbo/events/status/StatusPingEvent.java b/src/main/java/com/loohp/limbo/events/status/StatusPingEvent.java index d076322..a698b00 100644 --- a/src/main/java/com/loohp/limbo/events/status/StatusPingEvent.java +++ b/src/main/java/com/loohp/limbo/events/status/StatusPingEvent.java @@ -1,82 +1,81 @@ package com.loohp.limbo.events.status; -import java.awt.image.BufferedImage; - import com.loohp.limbo.events.Event; import com.loohp.limbo.server.ClientConnection; - import net.md_5.bungee.api.chat.BaseComponent; +import java.awt.image.BufferedImage; + public class StatusPingEvent extends Event { - private ClientConnection connection; - private String version; - private int protocol; - private BaseComponent[] motd; - private int maxPlayers; - private int playersOnline; - private BufferedImage favicon; + private final ClientConnection connection; + private String version; + private int protocol; + private BaseComponent[] motd; + private int maxPlayers; + private int playersOnline; + private BufferedImage favicon; - public StatusPingEvent(ClientConnection connection, String version, int protocol, BaseComponent[] motd, int maxPlayers, int playersOnline, BufferedImage favicon) { - this.connection = connection; - this.version = version; - this.protocol = protocol; - this.motd = motd; - this.maxPlayers = maxPlayers; - this.playersOnline = playersOnline; - this.favicon = favicon; - } - - public ClientConnection getConnection() { - return connection; - } + public StatusPingEvent(ClientConnection connection, String version, int protocol, BaseComponent[] motd, int maxPlayers, int playersOnline, BufferedImage favicon) { + this.connection = connection; + this.version = version; + this.protocol = protocol; + this.motd = motd; + this.maxPlayers = maxPlayers; + this.playersOnline = playersOnline; + this.favicon = favicon; + } - public String getVersion() { - return version; - } + public ClientConnection getConnection() { + return connection; + } - public void setVersion(String version) { - this.version = version; - } + public String getVersion() { + return version; + } - public int getProtocol() { - return protocol; - } + public void setVersion(String version) { + this.version = version; + } - public void setProtocol(int protocol) { - this.protocol = protocol; - } + public int getProtocol() { + return protocol; + } - public BaseComponent[] getMotd() { - return motd; - } + public void setProtocol(int protocol) { + this.protocol = protocol; + } - public void setMotd(BaseComponent[] motd) { - this.motd = motd; - } + public BaseComponent[] getMotd() { + return motd; + } - public int getMaxPlayers() { - return maxPlayers; - } + public void setMotd(BaseComponent[] motd) { + this.motd = motd; + } - public void setMaxPlayers(int maxPlayers) { - this.maxPlayers = maxPlayers; - } + public int getMaxPlayers() { + return maxPlayers; + } - public int getPlayersOnline() { - return playersOnline; - } + public void setMaxPlayers(int maxPlayers) { + this.maxPlayers = maxPlayers; + } - public void setPlayersOnline(int playersOnline) { - this.playersOnline = playersOnline; - } + public int getPlayersOnline() { + return playersOnline; + } - public BufferedImage getFavicon() { - return favicon; - } + public void setPlayersOnline(int playersOnline) { + this.playersOnline = playersOnline; + } - public void setFavicon(BufferedImage favicon) { - this.favicon = favicon; - } + public BufferedImage getFavicon() { + return favicon; + } + + public void setFavicon(BufferedImage favicon) { + this.favicon = favicon; + } } diff --git a/src/main/java/com/loohp/limbo/file/FileConfiguration.java b/src/main/java/com/loohp/limbo/file/FileConfiguration.java index feaaa8c..3ef2128 100644 --- a/src/main/java/com/loohp/limbo/file/FileConfiguration.java +++ b/src/main/java/com/loohp/limbo/file/FileConfiguration.java @@ -1,148 +1,137 @@ package com.loohp.limbo.file; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.io.Reader; -import java.nio.charset.StandardCharsets; -import java.util.LinkedHashMap; -import java.util.Map; - +import com.loohp.limbo.utils.YamlOrder; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.representer.Representer; -import com.loohp.limbo.utils.YamlOrder; +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.util.LinkedHashMap; +import java.util.Map; public class FileConfiguration { - - private Map mapping; - private String header; - - public FileConfiguration(File file) throws IOException { - if (file.exists()) { - InputStreamReader reader = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8); - reloadConfig(reader); - reader.close(); - } else { - mapping = new LinkedHashMap<>(); - } - } - - public FileConfiguration(InputStream input){ - reloadConfig(new InputStreamReader(input, StandardCharsets.UTF_8)); - } - - public FileConfiguration(Reader reader){ - reloadConfig(reader); - } - - public FileConfiguration reloadConfig(File file) throws FileNotFoundException { - return reloadConfig(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)); - } - - public FileConfiguration reloadConfig(InputStream input) { - return reloadConfig(new InputStreamReader(input, StandardCharsets.UTF_8)); - } - - public FileConfiguration reloadConfig(Reader reader) { - Yaml yml = new Yaml(); - mapping = yml.load(reader); - return this; - } - - public void setHeader(String header) { - this.header = header; - } - - @SuppressWarnings("unchecked") - public T get(String key, Class returnType) { - try { - String[] tree = key.split("\\."); - Map map = mapping; - for (int i = 0; i < tree.length - 1; i++) { - map = (Map) map.get(tree[i]); - } - if (returnType.equals(String.class)) { - return (T) map.get(tree[tree.length - 1]).toString(); - } - return returnType.cast(map.get(tree[tree.length - 1])); - } catch (Exception e) { - return null; - } - } - - @SuppressWarnings("unchecked") - public void set(String key, T value) { - String[] tree = key.split("\\."); - Map map = mapping; - for (int i = 0; i < tree.length - 1; i++) { - Map map1 = (Map) map.get(tree[i]); - if (map1 == null) { - map1 = new LinkedHashMap<>(); - map.put(tree[i], map1); - } - map = map1; - } - if (value != null) { - map.put(tree[tree.length - 1], (T) value); - } else { - map.remove(tree[tree.length - 1]); - } - } - - public String saveToString() throws IOException { - DumperOptions options = new DumperOptions(); + + private Map mapping; + private String header; + + public FileConfiguration(File file) throws IOException { + if (file.exists()) { + InputStreamReader reader = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8); + reloadConfig(reader); + reader.close(); + } else { + mapping = new LinkedHashMap<>(); + } + } + + public FileConfiguration(InputStream input) { + reloadConfig(new InputStreamReader(input, StandardCharsets.UTF_8)); + } + + public FileConfiguration(Reader reader) { + reloadConfig(reader); + } + + public FileConfiguration reloadConfig(File file) throws FileNotFoundException { + return reloadConfig(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)); + } + + public FileConfiguration reloadConfig(InputStream input) { + return reloadConfig(new InputStreamReader(input, StandardCharsets.UTF_8)); + } + + public FileConfiguration reloadConfig(Reader reader) { + Yaml yml = new Yaml(); + mapping = yml.load(reader); + return this; + } + + public void setHeader(String header) { + this.header = header; + } + + @SuppressWarnings("unchecked") + public T get(String key, Class returnType) { + try { + String[] tree = key.split("\\."); + Map map = mapping; + for (int i = 0; i < tree.length - 1; i++) { + map = (Map) map.get(tree[i]); + } + if (returnType.equals(String.class)) { + return (T) map.get(tree[tree.length - 1]).toString(); + } + return returnType.cast(map.get(tree[tree.length - 1])); + } catch (Exception e) { + return null; + } + } + + @SuppressWarnings("unchecked") + public void set(String key, T value) { + String[] tree = key.split("\\."); + Map map = mapping; + for (int i = 0; i < tree.length - 1; i++) { + Map map1 = (Map) map.get(tree[i]); + if (map1 == null) { + map1 = new LinkedHashMap<>(); + map.put(tree[i], map1); + } + map = map1; + } + if (value != null) { + map.put(tree[tree.length - 1], value); + } else { + map.remove(tree[tree.length - 1]); + } + } + + public String saveToString() throws IOException { + DumperOptions options = new DumperOptions(); options.setIndent(2); options.setPrettyFlow(true); options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); Representer customRepresenter = new Representer(); YamlOrder customProperty = new YamlOrder(); customRepresenter.setPropertyUtils(customProperty); - Yaml yaml = new Yaml(customRepresenter, options); - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - PrintWriter pw = new PrintWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8)); - if (header != null) { - pw.println("#" + header.replace("\n", "\n#")); - } - yaml.dump(mapping, pw); - pw.flush(); - pw.close(); - - String str = new String(out.toByteArray(), StandardCharsets.UTF_8); - - return str; - } - - public void saveConfig(File file) throws IOException { - DumperOptions options = new DumperOptions(); + Yaml yaml = new Yaml(customRepresenter, options); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + PrintWriter pw = new PrintWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8)); + if (header != null) { + pw.println("#" + header.replace("\n", "\n#")); + } + yaml.dump(mapping, pw); + pw.flush(); + pw.close(); + + String str = new String(out.toByteArray(), StandardCharsets.UTF_8); + + return str; + } + + public void saveConfig(File file) throws IOException { + DumperOptions options = new DumperOptions(); options.setIndent(2); options.setPrettyFlow(true); options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); Representer customRepresenter = new Representer(); YamlOrder customProperty = new YamlOrder(); customRepresenter.setPropertyUtils(customProperty); - Yaml yaml = new Yaml(customRepresenter, options); - - if (file.getParentFile() != null) { - file.getParentFile().mkdirs(); - } - - PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)); - if (header != null) { - pw.println("#" + header.replace("\n", "\n#")); - } - yaml.dump(mapping, pw); - pw.flush(); - pw.close(); - } + Yaml yaml = new Yaml(customRepresenter, options); + + if (file.getParentFile() != null) { + file.getParentFile().mkdirs(); + } + + PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)); + if (header != null) { + pw.println("#" + header.replace("\n", "\n#")); + } + yaml.dump(mapping, pw); + pw.flush(); + pw.close(); + } } diff --git a/src/main/java/com/loohp/limbo/file/ServerProperties.java b/src/main/java/com/loohp/limbo/file/ServerProperties.java index 203f4f1..da431a8 100644 --- a/src/main/java/com/loohp/limbo/file/ServerProperties.java +++ b/src/main/java/com/loohp/limbo/file/ServerProperties.java @@ -1,202 +1,193 @@ package com.loohp.limbo.file; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.nio.charset.StandardCharsets; -import java.util.Map.Entry; -import java.util.Optional; -import java.util.Properties; - -import javax.imageio.ImageIO; - import com.loohp.limbo.Limbo; import com.loohp.limbo.location.Location; import com.loohp.limbo.utils.GameMode; import com.loohp.limbo.utils.NamespacedKey; import com.loohp.limbo.world.World; +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.Properties; + public class ServerProperties { - - public static final String COMMENT = "For explaination of what each of the options does, please visit:\nhttps://github.com/LOOHP/Limbo/blob/master/src/main/resources/server.properties"; - private File file; - private int maxPlayers; - private int serverPort; - private String serverIp; - private NamespacedKey levelName; - private String schemFileName; - private NamespacedKey levelDimension; - private GameMode defaultGamemode; - private Location worldSpawn; - private boolean reducedDebugInfo; - private boolean allowFlight; - private String motdJson; - private String versionString; - private int protocol; - private boolean bungeecord; - private int viewDistance; - private double ticksPerSecond; - private boolean handshakeVerbose; - - Optional favicon; + public static final String COMMENT = "For explaination of what each of the options does, please visit:\nhttps://github.com/LOOHP/Limbo/blob/master/src/main/resources/server.properties"; + Optional favicon; + private final File file; + private final int maxPlayers; + private final int serverPort; + private final String serverIp; + private final NamespacedKey levelName; + private final String schemFileName; + private final NamespacedKey levelDimension; + private final GameMode defaultGamemode; + private Location worldSpawn; + private final boolean reducedDebugInfo; + private final boolean allowFlight; + private final String motdJson; + private final String versionString; + private final int protocol; + private final boolean bungeecord; + private final int viewDistance; + private final double ticksPerSecond; + private final boolean handshakeVerbose; - public ServerProperties(File file) throws IOException { - this.file = file; - - Properties def = new Properties(); - InputStreamReader defStream = new InputStreamReader(getClass().getClassLoader().getResourceAsStream("server.properties"), StandardCharsets.UTF_8); - def.load(defStream); - defStream.close(); - - Properties prop = new Properties(); - InputStreamReader stream = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8); - prop.load(stream); - stream.close(); - - for (Entry entry : def.entrySet()) { - String key = entry.getKey().toString(); - String value = entry.getValue().toString(); - prop.putIfAbsent(key, value); - } - PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)); - prop.store(pw, COMMENT); - pw.close(); + public ServerProperties(File file) throws IOException { + this.file = file; - protocol = Limbo.getInstance().serverImplmentationProtocol; + Properties def = new Properties(); + InputStreamReader defStream = new InputStreamReader(getClass().getClassLoader().getResourceAsStream("server.properties"), StandardCharsets.UTF_8); + def.load(defStream); + defStream.close(); - maxPlayers = Integer.parseInt(prop.getProperty("max-players")); - serverPort = Integer.parseInt(prop.getProperty("server-port")); - serverIp = prop.getProperty("server-ip"); - String[] level = prop.getProperty("level-name").split(";"); - levelName = new NamespacedKey(level[0]); - schemFileName = level[1]; - levelDimension = new NamespacedKey(prop.getProperty("level-dimension")); - defaultGamemode = GameMode.fromName(new NamespacedKey(prop.getProperty("default-gamemode")).getKey()); - String[] locStr = prop.getProperty("world-spawn").split(";"); - World world = Limbo.getInstance().getWorld(locStr[0]); - double x = Double.parseDouble(locStr[1]); - double y = Double.parseDouble(locStr[2]); - double z = Double.parseDouble(locStr[3]); - float yaw = Float.parseFloat(locStr[4]); - float pitch = Float.parseFloat(locStr[5]); - worldSpawn = new Location(world, x, y, z, yaw, pitch); - reducedDebugInfo = Boolean.parseBoolean(prop.getProperty("reduced-debug-info")); - allowFlight = Boolean.parseBoolean(prop.getProperty("allow-flight")); - motdJson = prop.getProperty("motd"); - versionString = prop.getProperty("version"); - bungeecord = Boolean.parseBoolean(prop.getProperty("bungeecord")); - viewDistance = Integer.parseInt(prop.getProperty("view-distance")); - ticksPerSecond = Double.parseDouble(prop.getProperty("ticks-per-second")); - handshakeVerbose = Boolean.parseBoolean(prop.getProperty("handshake-verbose")); - - File png = new File("server-icon.png"); - if (png.exists()) { - try { - BufferedImage image = ImageIO.read(png); - if (image.getHeight() == 64 && image.getWidth() == 64) { - favicon = Optional.of(image); - } else { - Limbo.getInstance().getConsole().sendMessage("Unable to load server-icon.png! The image is not 64 x 64 in size!"); - } - } catch (Exception e) { - Limbo.getInstance().getConsole().sendMessage("Unable to load server-icon.png! Is it a png image?"); - } - } else { - Limbo.getInstance().getConsole().sendMessage("No server-icon.png found"); - favicon = Optional.empty(); - } + Properties prop = new Properties(); + InputStreamReader stream = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8); + prop.load(stream); + stream.close(); - Limbo.getInstance().getConsole().sendMessage("Loaded server.properties"); - } - - public String getServerImplementationVersion() { - return Limbo.getInstance().serverImplementationVersion; - } + for (Entry entry : def.entrySet()) { + String key = entry.getKey().toString(); + String value = entry.getValue().toString(); + prop.putIfAbsent(key, value); + } + PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)); + prop.store(pw, COMMENT); + pw.close(); - public boolean isBungeecord() { - return bungeecord; - } + protocol = Limbo.getInstance().serverImplmentationProtocol; - public Optional getFavicon() { - return favicon; - } + maxPlayers = Integer.parseInt(prop.getProperty("max-players")); + serverPort = Integer.parseInt(prop.getProperty("server-port")); + serverIp = prop.getProperty("server-ip"); + String[] level = prop.getProperty("level-name").split(";"); + levelName = new NamespacedKey(level[0]); + schemFileName = level[1]; + levelDimension = new NamespacedKey(prop.getProperty("level-dimension")); + defaultGamemode = GameMode.fromName(new NamespacedKey(prop.getProperty("default-gamemode")).getKey()); + String[] locStr = prop.getProperty("world-spawn").split(";"); + World world = Limbo.getInstance().getWorld(locStr[0]); + double x = Double.parseDouble(locStr[1]); + double y = Double.parseDouble(locStr[2]); + double z = Double.parseDouble(locStr[3]); + float yaw = Float.parseFloat(locStr[4]); + float pitch = Float.parseFloat(locStr[5]); + worldSpawn = new Location(world, x, y, z, yaw, pitch); + reducedDebugInfo = Boolean.parseBoolean(prop.getProperty("reduced-debug-info")); + allowFlight = Boolean.parseBoolean(prop.getProperty("allow-flight")); + motdJson = prop.getProperty("motd"); + versionString = prop.getProperty("version"); + bungeecord = Boolean.parseBoolean(prop.getProperty("bungeecord")); + viewDistance = Integer.parseInt(prop.getProperty("view-distance")); + ticksPerSecond = Double.parseDouble(prop.getProperty("ticks-per-second")); + handshakeVerbose = Boolean.parseBoolean(prop.getProperty("handshake-verbose")); - public File getFile() { - return file; - } + File png = new File("server-icon.png"); + if (png.exists()) { + try { + BufferedImage image = ImageIO.read(png); + if (image.getHeight() == 64 && image.getWidth() == 64) { + favicon = Optional.of(image); + } else { + Limbo.getInstance().getConsole().sendMessage("Unable to load server-icon.png! The image is not 64 x 64 in size!"); + } + } catch (Exception e) { + Limbo.getInstance().getConsole().sendMessage("Unable to load server-icon.png! Is it a png image?"); + } + } else { + Limbo.getInstance().getConsole().sendMessage("No server-icon.png found"); + favicon = Optional.empty(); + } - public int getMaxPlayers() { - return maxPlayers; - } + Limbo.getInstance().getConsole().sendMessage("Loaded server.properties"); + } - public int getServerPort() { - return serverPort; - } + public String getServerImplementationVersion() { + return Limbo.getInstance().serverImplementationVersion; + } - public String getServerIp() { - return serverIp; - } + public boolean isBungeecord() { + return bungeecord; + } - public NamespacedKey getLevelName() { - return levelName; - } + public Optional getFavicon() { + return favicon; + } - public String getSchemFileName() { - return schemFileName; - } + public File getFile() { + return file; + } - public NamespacedKey getLevelDimension() { - return levelDimension; - } + public int getMaxPlayers() { + return maxPlayers; + } - public GameMode getDefaultGamemode() { - return defaultGamemode; - } + public int getServerPort() { + return serverPort; + } - public Location getWorldSpawn() { - return worldSpawn; - } + public String getServerIp() { + return serverIp; + } - public void setWorldSpawn(Location location) { - this.worldSpawn = location; - } + public NamespacedKey getLevelName() { + return levelName; + } - public boolean isReducedDebugInfo() { - return reducedDebugInfo; - } + public String getSchemFileName() { + return schemFileName; + } - public boolean isAllowFlight() { - return allowFlight; - } + public NamespacedKey getLevelDimension() { + return levelDimension; + } - public String getMotdJson() { - return motdJson; - } + public GameMode getDefaultGamemode() { + return defaultGamemode; + } - public String getVersionString() { - return versionString; - } + public Location getWorldSpawn() { + return worldSpawn; + } - public int getProtocol() { - return protocol; - } - - public int getViewDistance() { - return viewDistance; - } - - public double getDefinedTicksPerSecond() { - return ticksPerSecond; - } + public void setWorldSpawn(Location location) { + this.worldSpawn = location; + } - public boolean handshakeVerboseEnabled() { - return handshakeVerbose; - } + public boolean isReducedDebugInfo() { + return reducedDebugInfo; + } + + public boolean isAllowFlight() { + return allowFlight; + } + + public String getMotdJson() { + return motdJson; + } + + public String getVersionString() { + return versionString; + } + + public int getProtocol() { + return protocol; + } + + public int getViewDistance() { + return viewDistance; + } + + public double getDefinedTicksPerSecond() { + return ticksPerSecond; + } + + public boolean handshakeVerboseEnabled() { + return handshakeVerbose; + } } diff --git a/src/main/java/com/loohp/limbo/inventory/EquipmentSlot.java b/src/main/java/com/loohp/limbo/inventory/EquipmentSlot.java index eb35bde..6ef003f 100644 --- a/src/main/java/com/loohp/limbo/inventory/EquipmentSlot.java +++ b/src/main/java/com/loohp/limbo/inventory/EquipmentSlot.java @@ -1,12 +1,12 @@ package com.loohp.limbo.inventory; public enum EquipmentSlot { - - MAINHAND, - OFFHAND, - HELMENT, - CHESTPLATE, - LEGGINGS, - BOOTS; + + MAINHAND, + OFFHAND, + HELMENT, + CHESTPLATE, + LEGGINGS, + BOOTS } diff --git a/src/main/java/com/loohp/limbo/location/Location.java b/src/main/java/com/loohp/limbo/location/Location.java index 5f0ebf4..1c059be 100644 --- a/src/main/java/com/loohp/limbo/location/Location.java +++ b/src/main/java/com/loohp/limbo/location/Location.java @@ -6,102 +6,148 @@ import com.loohp.limbo.world.BlockState; import com.loohp.limbo.world.World; public class Location implements Cloneable { - - private World world; - private double x; - private double y; - private double z; - private float yaw; - private float pitch; - - public Location(World world, double x, double y, double z, float yaw, float pitch) { - this.world = world; - this.x = x; - this.y = y; - this.z = z; - this.yaw = yaw; - this.pitch = pitch; - } - - public Location(World world, double x, double y, double z) { - this(world, x, y, z, 0, 0); - } - - @Override - public Location clone() { - try { + + private World world; + private double x; + private double y; + private double z; + private float yaw; + private float pitch; + + public Location(World world, double x, double y, double z, float yaw, float pitch) { + this.world = world; + this.x = x; + this.y = y; + this.z = z; + this.yaw = yaw; + this.pitch = pitch; + } + + public Location(World world, double x, double y, double z) { + this(world, x, y, z, 0, 0); + } + + /** + * Safely converts a double (location coordinate) to an int (block + * coordinate) + * + * @param loc Precise coordinate + * @return Block coordinate + */ + public static int locToBlock(double loc) { + return NumberConversions.floor(loc); + } + + /** + * Normalizes the given yaw angle to a value between +/-180 + * degrees. + * + * @param yaw the yaw in degrees + * @return the normalized yaw in degrees + * @see Location#getYaw() + */ + public static float normalizeYaw(float yaw) { + yaw %= 360.0f; + if (yaw >= 180.0f) { + yaw -= 360.0f; + } else if (yaw < -180.0f) { + yaw += 360.0f; + } + return yaw; + } + + /** + * Normalizes the given pitch angle to a value between +/-90 + * degrees. + * + * @param pitch the pitch in degrees + * @return the normalized pitch in degrees + * @see Location#getPitch() + */ + public static float normalizePitch(float pitch) { + if (pitch > 90.0f) { + pitch = 90.0f; + } else if (pitch < -90.0f) { + pitch = -90.0f; + } + return pitch; + } + + @Override + public Location clone() { + try { return (Location) super.clone(); } catch (CloneNotSupportedException e) { throw new Error(e); } - } - - public BlockState getBlockState() { - return world.getBlock((int) x,(int) y,(int) z); - } - - public void setBlockState(BlockState state) { - world.setBlock((int) x, (int) y, (int) z, state); - } - - public boolean isWorldLoaded() { - return Limbo.getInstance().getWorld(world.getName()) != null; - } + } - public World getWorld() { - return world; - } + public BlockState getBlockState() { + return world.getBlock((int) x, (int) y, (int) z); + } - public void setWorld(World world) { - this.world = world; - } + public void setBlockState(BlockState state) { + world.setBlock((int) x, (int) y, (int) z, state); + } - public double getX() { - return x; - } + public boolean isWorldLoaded() { + return Limbo.getInstance().getWorld(world.getName()) != null; + } - public void setX(double x) { - this.x = x; - } + public World getWorld() { + return world; + } - public double getY() { - return y; - } + public void setWorld(World world) { + this.world = world; + } - public void setY(double y) { - this.y = y; - } + public double getX() { + return x; + } - public double getZ() { - return z; - } + public void setX(double x) { + this.x = x; + } - public void setZ(double z) { - this.z = z; - } + public double getY() { + return y; + } - public float getYaw() { - return yaw; - } + public void setY(double y) { + this.y = y; + } - public void setYaw(float yaw) { - this.yaw = yaw; - } + public double getZ() { + return z; + } - public float getPitch() { - return pitch; - } + public void setZ(double z) { + this.z = z; + } - public void setPitch(float pitch) { - this.pitch = pitch; - } - - /** + public float getYaw() { + return yaw; + } + + public void setYaw(float yaw) { + this.yaw = yaw; + } + + public float getPitch() { + return pitch; + } + + public void setPitch(float pitch) { + this.pitch = pitch; + } + + /** * Gets a unit-vector pointing in the direction that this Location is * facing. * * @return a vector pointing the direction of this location's {@link - * #getPitch() pitch} and {@link #getYaw() yaw} + * #getPitch() pitch} and {@link #getYaw() yaw} */ public Vector getDirection() { Vector vector = new Vector(); @@ -158,10 +204,10 @@ public class Location implements Cloneable { /** * Adds the location by another. * - * @see Vector * @param vec The other location * @return the same location * @throws IllegalArgumentException for differing worlds + * @see Vector */ public Location add(Location vec) { if (vec == null || vec.getWorld() != getWorld()) { @@ -177,9 +223,9 @@ public class Location implements Cloneable { /** * Adds the location by a vector. * - * @see Vector * @param vec Vector to use * @return the same location + * @see Vector */ public Location add(Vector vec) { this.x += vec.getX(); @@ -191,11 +237,11 @@ public class Location implements Cloneable { /** * Adds the location by another. Not world-aware. * - * @see Vector * @param x X coordinate * @param y Y coordinate * @param z Z coordinate * @return the same location + * @see Vector */ public Location add(double x, double y, double z) { this.x += x; @@ -207,10 +253,10 @@ public class Location implements Cloneable { /** * Subtracts the location by another. * - * @see Vector * @param vec The other location * @return the same location * @throws IllegalArgumentException for differing worlds + * @see Vector */ public Location subtract(Location vec) { if (vec == null || vec.getWorld() != getWorld()) { @@ -226,9 +272,9 @@ public class Location implements Cloneable { /** * Subtracts the location by a vector. * - * @see Vector * @param vec The vector to use * @return the same location + * @see Vector */ public Location subtract(Vector vec) { this.x -= vec.getX(); @@ -241,11 +287,11 @@ public class Location implements Cloneable { * Subtracts the location by another. Not world-aware and * orientation independent. * - * @see Vector * @param x X coordinate * @param y Y coordinate * @param z Z coordinate * @return the same location + * @see Vector */ public Location subtract(double x, double y, double z) { this.x -= x; @@ -348,7 +394,7 @@ public class Location implements Cloneable { * Constructs a new {@link Vector} based on this Location * * @return New Vector containing the coordinates represented by this - * Location + * Location */ public Vector toVector() { return new Vector(x, y, z); @@ -367,58 +413,12 @@ public class Location implements Cloneable { NumberConversions.checkFinite(yaw, "yaw not finite"); } - /** - * Safely converts a double (location coordinate) to an int (block - * coordinate) - * - * @param loc Precise coordinate - * @return Block coordinate - */ - public static int locToBlock(double loc) { - return NumberConversions.floor(loc); + @Override + public String toString() { + return "Location{" + "world=" + world + ",x=" + x + ",y=" + y + ",z=" + z + ",pitch=" + pitch + ",yaw=" + yaw + "}"; } - /** - * Normalizes the given yaw angle to a value between +/-180 - * degrees. - * - * @param yaw the yaw in degrees - * @return the normalized yaw in degrees - * @see Location#getYaw() - */ - public static float normalizeYaw(float yaw) { - yaw %= 360.0f; - if (yaw >= 180.0f) { - yaw -= 360.0f; - } else if (yaw < -180.0f) { - yaw += 360.0f; - } - return yaw; - } - - /** - * Normalizes the given pitch angle to a value between +/-90 - * degrees. - * - * @param pitch the pitch in degrees - * @return the normalized pitch in degrees - * @see Location#getPitch() - */ - public static float normalizePitch(float pitch) { - if (pitch > 90.0f) { - pitch = 90.0f; - } else if (pitch < -90.0f) { - pitch = -90.0f; - } - return pitch; - } - - @Override - public String toString() { - return "Location{" + "world=" + world + ",x=" + x + ",y=" + y + ",z=" + z + ",pitch=" + pitch + ",yaw=" + yaw + "}"; - } - - @Override + @Override public boolean equals(Object obj) { if (obj == null) { return false; @@ -445,10 +445,7 @@ public class Location implements Cloneable { if (Float.floatToIntBits(this.pitch) != Float.floatToIntBits(other.pitch)) { return false; } - if (Float.floatToIntBits(this.yaw) != Float.floatToIntBits(other.yaw)) { - return false; - } - return true; + return Float.floatToIntBits(this.yaw) == Float.floatToIntBits(other.yaw); } @Override diff --git a/src/main/java/com/loohp/limbo/location/Vector.java b/src/main/java/com/loohp/limbo/location/Vector.java index 19d4d45..74bcd9a 100644 --- a/src/main/java/com/loohp/limbo/location/Vector.java +++ b/src/main/java/com/loohp/limbo/location/Vector.java @@ -1,12 +1,12 @@ package com.loohp.limbo.location; -import java.util.Random; - import com.google.common.base.Preconditions; import com.google.common.primitives.Doubles; import com.loohp.limbo.utils.NumberConversions; import com.loohp.limbo.world.World; +import java.util.Random; + /** * Represents a mutable vector. Because the components of Vectors are mutable, * storing Vectors long term may be dangerous if passing code modifies the @@ -15,13 +15,11 @@ import com.loohp.limbo.world.World; */ public class Vector implements Cloneable { - private static Random random = new Random(); - /** * Threshold for fuzzy equals(). */ private static final double epsilon = 0.000001; - + private static final Random random = new Random(); protected double x; protected double y; protected double z; @@ -74,6 +72,47 @@ public class Vector implements Cloneable { this.z = z; } + /** + * Get the threshold used for equals(). + * + * @return The epsilon. + */ + public static double getEpsilon() { + return epsilon; + } + + /** + * Gets the minimum components of two vectors. + * + * @param v1 The first vector. + * @param v2 The second vector. + * @return minimum + */ + public static Vector getMinimum(Vector v1, Vector v2) { + return new Vector(Math.min(v1.x, v2.x), Math.min(v1.y, v2.y), Math.min(v1.z, v2.z)); + } + + /** + * Gets the maximum components of two vectors. + * + * @param v1 The first vector. + * @param v2 The second vector. + * @return maximum + */ + public static Vector getMaximum(Vector v1, Vector v2) { + return new Vector(Math.max(v1.x, v2.x), Math.max(v1.y, v2.y), Math.max(v1.z, v2.z)); + } + + /** + * Gets a random vector with components having a random value between 0 + * and 1. + * + * @return A random vector. + */ + public static Vector getRandom() { + return new Vector(random.nextDouble(), random.nextDouble(), random.nextDouble()); + } + /** * Adds a vector to this one * @@ -400,7 +439,7 @@ public class Vector implements Cloneable { * Matrix. * * @param angle the angle to rotate the vector about. This angle is passed - * in radians + * in radians * @return the same vector */ public Vector rotateAroundX(double angle) { @@ -421,7 +460,7 @@ public class Vector implements Cloneable { * Matrix. * * @param angle the angle to rotate the vector about. This angle is passed - * in radians + * in radians * @return the same vector */ public Vector rotateAroundY(double angle) { @@ -442,7 +481,7 @@ public class Vector implements Cloneable { * Matrix. * * @param angle the angle to rotate the vector about. This angle is passed - * in radians + * in radians * @return the same vector */ public Vector rotateAroundZ(double angle) { @@ -466,14 +505,14 @@ public class Vector implements Cloneable { * with the scaling of a non-unit axis vector, you can use * {@link Vector#rotateAroundNonUnitAxis(Vector, double)}. * - * @param axis the axis to rotate the vector around. If the passed vector is - * not of length 1, it gets copied and normalized before using it for the - * rotation. Please use {@link Vector#normalize()} on the instance before - * passing it to this method + * @param axis the axis to rotate the vector around. If the passed vector is + * not of length 1, it gets copied and normalized before using it for the + * rotation. Please use {@link Vector#normalize()} on the instance before + * passing it to this method * @param angle the angle to rotate the vector around the axis * @return the same vector * @throws IllegalArgumentException if the provided axis vector instance is - * null + * null */ public Vector rotateAroundAxis(Vector axis, double angle) throws IllegalArgumentException { Preconditions.checkArgument(axis != null, "The provided axis vector was null"); @@ -495,11 +534,11 @@ public class Vector implements Cloneable { * about the scaling of the vector, use * {@link Vector#rotateAroundAxis(Vector, double)} * - * @param axis the axis to rotate the vector around. + * @param axis the axis to rotate the vector around. * @param angle the angle to rotate the vector around the axis * @return the same vector * @throws IllegalArgumentException if the provided axis vector instance is - * null + * null */ public Vector rotateAroundNonUnitAxis(Vector axis, double angle) throws IllegalArgumentException { Preconditions.checkArgument(axis != null, "The provided axis vector was null"); @@ -533,54 +572,6 @@ public class Vector implements Cloneable { return x; } - /** - * Gets the floored value of the X component, indicating the block that - * this vector is contained with. - * - * @return block X - */ - public int getBlockX() { - return NumberConversions.floor(x); - } - - /** - * Gets the Y component. - * - * @return The Y component. - */ - public double getY() { - return y; - } - - /** - * Gets the floored value of the Y component, indicating the block that - * this vector is contained with. - * - * @return block y - */ - public int getBlockY() { - return NumberConversions.floor(y); - } - - /** - * Gets the Z component. - * - * @return The Z component. - */ - public double getZ() { - return z; - } - - /** - * Gets the floored value of the Z component, indicating the block that - * this vector is contained with. - * - * @return block z - */ - public int getBlockZ() { - return NumberConversions.floor(z); - } - /** * Set the X component. * @@ -614,6 +605,25 @@ public class Vector implements Cloneable { return this; } + /** + * Gets the floored value of the X component, indicating the block that + * this vector is contained with. + * + * @return block X + */ + public int getBlockX() { + return NumberConversions.floor(x); + } + + /** + * Gets the Y component. + * + * @return The Y component. + */ + public double getY() { + return y; + } + /** * Set the Y component. * @@ -647,6 +657,25 @@ public class Vector implements Cloneable { return this; } + /** + * Gets the floored value of the Y component, indicating the block that + * this vector is contained with. + * + * @return block y + */ + public int getBlockY() { + return NumberConversions.floor(y); + } + + /** + * Gets the Z component. + * + * @return The Z component. + */ + public double getZ() { + return z; + } + /** * Set the Z component. * @@ -680,6 +709,16 @@ public class Vector implements Cloneable { return this; } + /** + * Gets the floored value of the Z component, indicating the block that + * this vector is contained with. + * + * @return block z + */ + public int getBlockZ() { + return NumberConversions.floor(z); + } + /** * Checks to see if two objects are equal. *

@@ -713,6 +752,15 @@ public class Vector implements Cloneable { return hash; } + /** + * Get the block vector of this vector. + * + * @return A block vector. + public BlockVector toBlockVector() { + return new BlockVector(x, y, z); + } + */ + /** * Get a new vector. * @@ -749,7 +797,7 @@ public class Vector implements Cloneable { * Gets a Location version of this vector. * * @param world The world to link the location to. - * @param yaw The desired yaw. + * @param yaw The desired yaw. * @param pitch The desired pitch. * @return the location */ @@ -757,15 +805,6 @@ public class Vector implements Cloneable { return new Location(world, x, y, z, yaw, pitch); } - /** - * Get the block vector of this vector. - * - * @return A block vector. - public BlockVector toBlockVector() { - return new BlockVector(x, y, z); - } - */ - /** * Check if each component of this Vector is finite. * @@ -777,47 +816,6 @@ public class Vector implements Cloneable { NumberConversions.checkFinite(z, "z not finite"); } - /** - * Get the threshold used for equals(). - * - * @return The epsilon. - */ - public static double getEpsilon() { - return epsilon; - } - - /** - * Gets the minimum components of two vectors. - * - * @param v1 The first vector. - * @param v2 The second vector. - * @return minimum - */ - public static Vector getMinimum(Vector v1, Vector v2) { - return new Vector(Math.min(v1.x, v2.x), Math.min(v1.y, v2.y), Math.min(v1.z, v2.z)); - } - - /** - * Gets the maximum components of two vectors. - * - * @param v1 The first vector. - * @param v2 The second vector. - * @return maximum - */ - public static Vector getMaximum(Vector v1, Vector v2) { - return new Vector(Math.max(v1.x, v2.x), Math.max(v1.y, v2.y), Math.max(v1.z, v2.z)); - } - - /** - * Gets a random vector with components having a random value between 0 - * and 1. - * - * @return A random vector. - */ - public static Vector getRandom() { - return new Vector(random.nextDouble(), random.nextDouble(), random.nextDouble()); - } - /* @Override public Map serialize() { diff --git a/src/main/java/com/loohp/limbo/metrics/Metrics.java b/src/main/java/com/loohp/limbo/metrics/Metrics.java index 5311354..010d6fb 100644 --- a/src/main/java/com/loohp/limbo/metrics/Metrics.java +++ b/src/main/java/com/loohp/limbo/metrics/Metrics.java @@ -1,32 +1,24 @@ package com.loohp.limbo.metrics; +import com.loohp.limbo.Limbo; +import com.loohp.limbo.file.FileConfiguration; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +import javax.net.ssl.HttpsURLConnection; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.File; import java.io.IOException; import java.net.URL; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Timer; -import java.util.TimerTask; -import java.util.UUID; +import java.nio.charset.StandardCharsets; +import java.util.*; import java.util.concurrent.Callable; import java.util.zip.GZIPOutputStream; -import javax.net.ssl.HttpsURLConnection; - -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; - -import com.loohp.limbo.Limbo; -import com.loohp.limbo.file.FileConfiguration; - /** * bStats collects some data for plugin authors. - * + *

* Check out https://bStats.org/ to learn more about bStats! */ @SuppressWarnings("unchecked") @@ -46,7 +38,7 @@ public class Metrics { // The uuid of the server private final String serverUUID; - + private final String limboVersion; // A list with all custom charts @@ -55,17 +47,17 @@ public class Metrics { /** * Class constructor. * - * @param name The name of the server software. - * @param serverUUID The uuid of the server. + * @param name The name of the server software. + * @param serverUUID The uuid of the server. * @param logFailedRequests Whether failed requests should be logged or not. - * @param logger The logger for the failed requests. - * @throws IOException + * @param logger The logger for the failed requests. + * @throws IOException */ public Metrics() throws IOException { - name = "Limbo"; - - // Get the config file - File configFile = new File("plugins/bStats", "config.yml"); + name = "Limbo"; + + // Get the config file + File configFile = new File("plugins/bStats", "config.yml"); FileConfiguration config = new FileConfiguration(configFile); // Check if the config file exists @@ -81,17 +73,17 @@ public class Metrics { // Inform the server owners about bStats config.setHeader( "bStats collects some data for plugin authors like how many servers are using their plugins.\n" + - "To honor their work, you should not disable it.\n" + - "This has nearly no effect on the server performance!\n" + - "Check out https://bStats.org/ to learn more :)" + "To honor their work, you should not disable it.\n" + + "This has nearly no effect on the server performance!\n" + + "Check out https://bStats.org/ to learn more :)" ); try { config.saveConfig(configFile); } catch (IOException e) { - e.printStackTrace(); + e.printStackTrace(); } } - + limboVersion = Limbo.getInstance().limboImplementationVersion; // Load the data @@ -99,28 +91,80 @@ public class Metrics { logFailedRequests = config.get("logFailedRequests", Boolean.class); if (config.get("enabled", Boolean.class)) { startSubmitting(); - } - - addCustomChart(new Metrics.SingleLineChart("players", new Callable() { - @Override - public Integer call() throws Exception { - return Limbo.getInstance().getPlayers().size(); - } - })); - - addCustomChart(new Metrics.SimplePie("limbo_version", new Callable() { - @Override - public String call() throws Exception { - return limboVersion; - } - })); + } - addCustomChart(new Metrics.SimplePie("minecraftVersion", new Callable() { - @Override - public String call() throws Exception { - return Limbo.getInstance().serverImplementationVersion; - } - })); + addCustomChart(new Metrics.SingleLineChart("players", new Callable() { + @Override + public Integer call() throws Exception { + return Limbo.getInstance().getPlayers().size(); + } + })); + + addCustomChart(new Metrics.SimplePie("limbo_version", new Callable() { + @Override + public String call() throws Exception { + return limboVersion; + } + })); + + addCustomChart(new Metrics.SimplePie("minecraftVersion", new Callable() { + @Override + public String call() throws Exception { + return Limbo.getInstance().serverImplementationVersion; + } + })); + } + + /** + * Sends the data to the bStats server. + * + * @param data The data to send. + * @throws Exception If the request failed. + */ + private static void sendData(JSONObject data) throws Exception { + if (data == null) { + throw new IllegalArgumentException("Data cannot be null!"); + } + HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection(); + + // Compress the data to save bandwidth + byte[] compressedData = compress(data.toString()); + + // Add headers + connection.setRequestMethod("POST"); + connection.addRequestProperty("Accept", "application/json"); + connection.addRequestProperty("Connection", "close"); + connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request + connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length)); + connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format + connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION); + + // Send data + connection.setDoOutput(true); + DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream()); + outputStream.write(compressedData); + outputStream.flush(); + outputStream.close(); + + connection.getInputStream().close(); // We don't care about the response - Just send our data :) + } + + /** + * Gzips the given String. + * + * @param str The string to gzip. + * @return The gzipped String. + * @throws IOException If the compression failed. + */ + private static byte[] compress(final String str) throws IOException { + if (str == null) { + return null; + } + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + GZIPOutputStream gzip = new GZIPOutputStream(outputStream); + gzip.write(str.getBytes(StandardCharsets.UTF_8)); + gzip.close(); + return outputStream.toByteArray(); } /** @@ -145,7 +189,7 @@ public class Metrics { public void run() { submitData(); } - }, 1000*60*5, 1000*60*30); + }, 1000 * 60 * 5, 1000 * 60 * 30); // Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start // WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted! // WARNING: Just don't do it! @@ -156,7 +200,7 @@ public class Metrics { * * @return The plugin specific data. */ - private JSONObject getPluginData() { + private JSONObject getPluginData() { JSONObject data = new JSONObject(); data.put("pluginName", name); // Append the name of the server software @@ -220,475 +264,6 @@ public class Metrics { } } - /** - * Sends the data to the bStats server. - * - * @param data The data to send. - * @throws Exception If the request failed. - */ - private static void sendData(JSONObject data) throws Exception { - if (data == null) { - throw new IllegalArgumentException("Data cannot be null!"); - } - HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection(); - - // Compress the data to save bandwidth - byte[] compressedData = compress(data.toString()); - - // Add headers - connection.setRequestMethod("POST"); - connection.addRequestProperty("Accept", "application/json"); - connection.addRequestProperty("Connection", "close"); - connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request - connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length)); - connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format - connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION); - - // Send data - connection.setDoOutput(true); - DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream()); - outputStream.write(compressedData); - outputStream.flush(); - outputStream.close(); - - connection.getInputStream().close(); // We don't care about the response - Just send our data :) - } - - /** - * Gzips the given String. - * - * @param str The string to gzip. - * @return The gzipped String. - * @throws IOException If the compression failed. - */ - private static byte[] compress(final String str) throws IOException { - if (str == null) { - return null; - } - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - GZIPOutputStream gzip = new GZIPOutputStream(outputStream); - gzip.write(str.getBytes("UTF-8")); - gzip.close(); - return outputStream.toByteArray(); - } - - /** - * Represents a custom chart. - */ - public static abstract class CustomChart { - - // The id of the chart - final String chartId; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - */ - CustomChart(String chartId) { - if (chartId == null || chartId.isEmpty()) { - throw new IllegalArgumentException("ChartId cannot be null or empty!"); - } - this.chartId = chartId; - } - - private JSONObject getRequestJsonObject() { - JSONObject chart = new JSONObject(); - chart.put("chartId", chartId); - try { - JSONObject data = getChartData(); - if (data == null) { - // If the data is null we don't send the chart. - return null; - } - chart.put("data", data); - } catch (Throwable t) { - if (logFailedRequests) { - Limbo.getInstance().getConsole().sendMessage("Failed to get data for custom chart with id " + chartId + "\n" + t); - } - return null; - } - return chart; - } - - protected abstract JSONObject getChartData() throws Exception; - - } - - /** - * Represents a custom simple pie. - */ - public static class SimplePie extends CustomChart { - - private final Callable callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public SimplePie(String chartId, Callable callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JSONObject getChartData() throws Exception { - JSONObject data = new JSONObject(); - String value = callable.call(); - if (value == null || value.isEmpty()) { - // Null = skip the chart - return null; - } - data.put("value", value); - return data; - } - } - - /** - * Represents a custom advanced pie. - */ - public static class AdvancedPie extends CustomChart { - - private final Callable> callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public AdvancedPie(String chartId, Callable> callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JSONObject getChartData() throws Exception { - JSONObject data = new JSONObject(); - JSONObject values = new JSONObject(); - Map map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - boolean allSkipped = true; - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue() == 0) { - continue; // Skip this invalid - } - allSkipped = false; - values.put(entry.getKey(), entry.getValue()); - } - if (allSkipped) { - // Null = skip the chart - return null; - } - data.put("values", values); - return data; - } - } - - /** - * Represents a custom drilldown pie. - */ - public static class DrilldownPie extends CustomChart { - - private final Callable>> callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public DrilldownPie(String chartId, Callable>> callable) { - super(chartId); - this.callable = callable; - } - - @Override - public JSONObject getChartData() throws Exception { - JSONObject data = new JSONObject(); - JSONObject values = new JSONObject(); - Map> map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - boolean reallyAllSkipped = true; - for (Map.Entry> entryValues : map.entrySet()) { - JSONObject value = new JSONObject(); - boolean allSkipped = true; - for (Map.Entry valueEntry : map.get(entryValues.getKey()).entrySet()) { - value.put(valueEntry.getKey(), valueEntry.getValue()); - allSkipped = false; - } - if (!allSkipped) { - reallyAllSkipped = false; - values.put(entryValues.getKey(), value); - } - } - if (reallyAllSkipped) { - // Null = skip the chart - return null; - } - data.put("values", values); - return data; - } - } - - /** - * Represents a custom single line chart. - */ - public static class SingleLineChart extends CustomChart { - - private final Callable callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public SingleLineChart(String chartId, Callable callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JSONObject getChartData() throws Exception { - JSONObject data = new JSONObject(); - int value = callable.call(); - if (value == 0) { - // Null = skip the chart - return null; - } - data.put("value", value); - return data; - } - - } - - /** - * Represents a custom multi line chart. - */ - public static class MultiLineChart extends CustomChart { - - private final Callable> callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public MultiLineChart(String chartId, Callable> callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JSONObject getChartData() throws Exception { - JSONObject data = new JSONObject(); - JSONObject values = new JSONObject(); - Map map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - boolean allSkipped = true; - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue() == 0) { - continue; // Skip this invalid - } - allSkipped = false; - values.put(entry.getKey(), entry.getValue()); - } - if (allSkipped) { - // Null = skip the chart - return null; - } - data.put("values", values); - return data; - } - - } - - /** - * Represents a custom simple bar chart. - */ - public static class SimpleBarChart extends CustomChart { - - private final Callable> callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public SimpleBarChart(String chartId, Callable> callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JSONObject getChartData() throws Exception { - JSONObject data = new JSONObject(); - JSONObject values = new JSONObject(); - Map map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - for (Map.Entry entry : map.entrySet()) { - JSONArray categoryValues = new JSONArray(); - categoryValues.add(entry.getValue()); - values.put(entry.getKey(), categoryValues); - } - data.put("values", values); - return data; - } - - } - - /** - * Represents a custom advanced bar chart. - */ - public static class AdvancedBarChart extends CustomChart { - - private final Callable> callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public AdvancedBarChart(String chartId, Callable> callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JSONObject getChartData() throws Exception { - JSONObject data = new JSONObject(); - JSONObject values = new JSONObject(); - Map map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - boolean allSkipped = true; - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue().length == 0) { - continue; // Skip this invalid - } - allSkipped = false; - JSONArray categoryValues = new JSONArray(); - for (int categoryValue : entry.getValue()) { - categoryValues.add(categoryValue); - } - values.put(entry.getKey(), categoryValues); - } - if (allSkipped) { - // Null = skip the chart - return null; - } - data.put("values", values); - return data; - } - - } - - /** - * Represents a custom simple map chart. - */ - public static abstract class SimpleMapChart extends CustomChart { - - /** - * Class constructor. - * - * @param chartId The id of the chart. - */ - public SimpleMapChart(String chartId) { - super(chartId); - } - - /** - * Gets the value of the chart. - * - * @return The value of the chart. - */ - public abstract Country getValue(); - - @Override - protected JSONObject getChartData() { - JSONObject data = new JSONObject(); - Country value = getValue(); - - if (value == null) { - // Null = skip the chart - return null; - } - data.put("value", value.getCountryIsoTag()); - return data; - } - - } - - /** - * Represents a custom advanced map chart. - */ - public static abstract class AdvancedMapChart extends CustomChart { - - /** - * Class constructor. - * - * @param chartId The id of the chart. - */ - public AdvancedMapChart(String chartId) { - super(chartId); - } - - /** - * Gets the value of the chart. - * - * @param valueMap Just an empty map. The only reason it exists is to make your life easier. - * You don't have to create a map yourself! - * @return The value of the chart. - */ - public abstract HashMap getValues(HashMap valueMap); - - @Override - protected JSONObject getChartData() { - JSONObject data = new JSONObject(); - JSONObject values = new JSONObject(); - HashMap map = getValues(new HashMap()); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - boolean allSkipped = true; - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue() == 0) { - continue; // Skip this invalid - } - allSkipped = false; - values.put(entry.getKey().getCountryIsoTag(), entry.getValue()); - } - if (allSkipped) { - // Null = skip the chart - return null; - } - data.put("values", values); - return data; - } - - } - /** * A enum which is used for custom maps. */ @@ -714,7 +289,7 @@ public class Metrics { AUSTRIA("AT", "Austria"), AUSTRALIA("AU", "Australia"), ARUBA("AW", "Aruba"), - ALAND_ISLANDS("AX", "Åland Islands"), + ALAND_ISLANDS("AX", "�land Islands"), AZERBAIJAN("AZ", "Azerbaijan"), BOSNIA_AND_HERZEGOVINA("BA", "Bosnia and Herzegovina"), BARBADOS("BB", "Barbados"), @@ -725,7 +300,7 @@ public class Metrics { BAHRAIN("BH", "Bahrain"), BURUNDI("BI", "Burundi"), BENIN("BJ", "Benin"), - SAINT_BARTHELEMY("BL", "Saint Barthélemy"), + SAINT_BARTHELEMY("BL", "Saint Barth�lemy"), BERMUDA("BM", "Bermuda"), BRUNEI("BN", "Brunei"), BOLIVIA("BO", "Bolivia"), @@ -743,7 +318,7 @@ public class Metrics { CENTRAL_AFRICAN_REPUBLIC("CF", "Central African Republic"), CONGO("CG", "Congo"), SWITZERLAND("CH", "Switzerland"), - COTE_D_IVOIRE("CI", "Côte d'Ivoire"), + COTE_D_IVOIRE("CI", "C�te d'Ivoire"), COOK_ISLANDS("CK", "Cook Islands"), CHILE("CL", "Chile"), CAMEROON("CM", "Cameroon"), @@ -752,7 +327,7 @@ public class Metrics { COSTA_RICA("CR", "Costa Rica"), CUBA("CU", "Cuba"), CAPE_VERDE("CV", "Cape Verde"), - CURACAO("CW", "Curaçao"), + CURACAO("CW", "Cura�ao"), CHRISTMAS_ISLAND("CX", "Christmas Island"), CYPRUS("CY", "Cyprus"), CZECH_REPUBLIC("CZ", "Czech Republic"), @@ -950,32 +525,14 @@ public class Metrics { ZAMBIA("ZM", "Zambia"), ZIMBABWE("ZW", "Zimbabwe"); - private String isoTag; - private String name; + private final String isoTag; + private final String name; Country(String isoTag, String name) { this.isoTag = isoTag; this.name = name; } - /** - * Gets the name of the country. - * - * @return The name of the country. - */ - public String getCountryName() { - return name; - } - - /** - * Gets the iso tag of the country. - * - * @return The iso tag of the country. - */ - public String getCountryIsoTag() { - return isoTag; - } - /** * Gets a country by it's iso tag. * @@ -996,12 +553,447 @@ public class Metrics { * * @param locale The locale. * @return The country from the giben locale or null if unknown country or - * if the locale does not contain a country. + * if the locale does not contain a country. */ public static Country byLocale(Locale locale) { return byIsoTag(locale.getCountry()); } + /** + * Gets the name of the country. + * + * @return The name of the country. + */ + public String getCountryName() { + return name; + } + + /** + * Gets the iso tag of the country. + * + * @return The iso tag of the country. + */ + public String getCountryIsoTag() { + return isoTag; + } + + } + + /** + * Represents a custom chart. + */ + public static abstract class CustomChart { + + // The id of the chart + final String chartId; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + */ + CustomChart(String chartId) { + if (chartId == null || chartId.isEmpty()) { + throw new IllegalArgumentException("ChartId cannot be null or empty!"); + } + this.chartId = chartId; + } + + private JSONObject getRequestJsonObject() { + JSONObject chart = new JSONObject(); + chart.put("chartId", chartId); + try { + JSONObject data = getChartData(); + if (data == null) { + // If the data is null we don't send the chart. + return null; + } + chart.put("data", data); + } catch (Throwable t) { + if (logFailedRequests) { + Limbo.getInstance().getConsole().sendMessage("Failed to get data for custom chart with id " + chartId + "\n" + t); + } + return null; + } + return chart; + } + + protected abstract JSONObject getChartData() throws Exception; + + } + + /** + * Represents a custom simple pie. + */ + public static class SimplePie extends CustomChart { + + private final Callable callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public SimplePie(String chartId, Callable callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JSONObject getChartData() throws Exception { + JSONObject data = new JSONObject(); + String value = callable.call(); + if (value == null || value.isEmpty()) { + // Null = skip the chart + return null; + } + data.put("value", value); + return data; + } + } + + /** + * Represents a custom advanced pie. + */ + public static class AdvancedPie extends CustomChart { + + private final Callable> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public AdvancedPie(String chartId, Callable> callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JSONObject getChartData() throws Exception { + JSONObject data = new JSONObject(); + JSONObject values = new JSONObject(); + Map map = callable.call(); + if (map == null || map.isEmpty()) { + // Null = skip the chart + return null; + } + boolean allSkipped = true; + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue() == 0) { + continue; // Skip this invalid + } + allSkipped = false; + values.put(entry.getKey(), entry.getValue()); + } + if (allSkipped) { + // Null = skip the chart + return null; + } + data.put("values", values); + return data; + } + } + + /** + * Represents a custom drilldown pie. + */ + public static class DrilldownPie extends CustomChart { + + private final Callable>> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public DrilldownPie(String chartId, Callable>> callable) { + super(chartId); + this.callable = callable; + } + + @Override + public JSONObject getChartData() throws Exception { + JSONObject data = new JSONObject(); + JSONObject values = new JSONObject(); + Map> map = callable.call(); + if (map == null || map.isEmpty()) { + // Null = skip the chart + return null; + } + boolean reallyAllSkipped = true; + for (Map.Entry> entryValues : map.entrySet()) { + JSONObject value = new JSONObject(); + boolean allSkipped = true; + for (Map.Entry valueEntry : map.get(entryValues.getKey()).entrySet()) { + value.put(valueEntry.getKey(), valueEntry.getValue()); + allSkipped = false; + } + if (!allSkipped) { + reallyAllSkipped = false; + values.put(entryValues.getKey(), value); + } + } + if (reallyAllSkipped) { + // Null = skip the chart + return null; + } + data.put("values", values); + return data; + } + } + + /** + * Represents a custom single line chart. + */ + public static class SingleLineChart extends CustomChart { + + private final Callable callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public SingleLineChart(String chartId, Callable callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JSONObject getChartData() throws Exception { + JSONObject data = new JSONObject(); + int value = callable.call(); + if (value == 0) { + // Null = skip the chart + return null; + } + data.put("value", value); + return data; + } + + } + + /** + * Represents a custom multi line chart. + */ + public static class MultiLineChart extends CustomChart { + + private final Callable> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public MultiLineChart(String chartId, Callable> callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JSONObject getChartData() throws Exception { + JSONObject data = new JSONObject(); + JSONObject values = new JSONObject(); + Map map = callable.call(); + if (map == null || map.isEmpty()) { + // Null = skip the chart + return null; + } + boolean allSkipped = true; + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue() == 0) { + continue; // Skip this invalid + } + allSkipped = false; + values.put(entry.getKey(), entry.getValue()); + } + if (allSkipped) { + // Null = skip the chart + return null; + } + data.put("values", values); + return data; + } + + } + + /** + * Represents a custom simple bar chart. + */ + public static class SimpleBarChart extends CustomChart { + + private final Callable> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public SimpleBarChart(String chartId, Callable> callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JSONObject getChartData() throws Exception { + JSONObject data = new JSONObject(); + JSONObject values = new JSONObject(); + Map map = callable.call(); + if (map == null || map.isEmpty()) { + // Null = skip the chart + return null; + } + for (Map.Entry entry : map.entrySet()) { + JSONArray categoryValues = new JSONArray(); + categoryValues.add(entry.getValue()); + values.put(entry.getKey(), categoryValues); + } + data.put("values", values); + return data; + } + + } + + /** + * Represents a custom advanced bar chart. + */ + public static class AdvancedBarChart extends CustomChart { + + private final Callable> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public AdvancedBarChart(String chartId, Callable> callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JSONObject getChartData() throws Exception { + JSONObject data = new JSONObject(); + JSONObject values = new JSONObject(); + Map map = callable.call(); + if (map == null || map.isEmpty()) { + // Null = skip the chart + return null; + } + boolean allSkipped = true; + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue().length == 0) { + continue; // Skip this invalid + } + allSkipped = false; + JSONArray categoryValues = new JSONArray(); + for (int categoryValue : entry.getValue()) { + categoryValues.add(categoryValue); + } + values.put(entry.getKey(), categoryValues); + } + if (allSkipped) { + // Null = skip the chart + return null; + } + data.put("values", values); + return data; + } + + } + + /** + * Represents a custom simple map chart. + */ + public static abstract class SimpleMapChart extends CustomChart { + + /** + * Class constructor. + * + * @param chartId The id of the chart. + */ + public SimpleMapChart(String chartId) { + super(chartId); + } + + /** + * Gets the value of the chart. + * + * @return The value of the chart. + */ + public abstract Country getValue(); + + @Override + protected JSONObject getChartData() { + JSONObject data = new JSONObject(); + Country value = getValue(); + + if (value == null) { + // Null = skip the chart + return null; + } + data.put("value", value.getCountryIsoTag()); + return data; + } + + } + + /** + * Represents a custom advanced map chart. + */ + public static abstract class AdvancedMapChart extends CustomChart { + + /** + * Class constructor. + * + * @param chartId The id of the chart. + */ + public AdvancedMapChart(String chartId) { + super(chartId); + } + + /** + * Gets the value of the chart. + * + * @param valueMap Just an empty map. The only reason it exists is to make your life easier. + * You don't have to create a map yourself! + * @return The value of the chart. + */ + public abstract HashMap getValues(HashMap valueMap); + + @Override + protected JSONObject getChartData() { + JSONObject data = new JSONObject(); + JSONObject values = new JSONObject(); + HashMap map = getValues(new HashMap()); + if (map == null || map.isEmpty()) { + // Null = skip the chart + return null; + } + boolean allSkipped = true; + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue() == 0) { + continue; // Skip this invalid + } + allSkipped = false; + values.put(entry.getKey().getCountryIsoTag(), entry.getValue()); + } + if (allSkipped) { + // Null = skip the chart + return null; + } + data.put("values", values); + return data; + } + } } \ No newline at end of file diff --git a/src/main/java/com/loohp/limbo/permissions/PermissionsManager.java b/src/main/java/com/loohp/limbo/permissions/PermissionsManager.java index d95547b..e6728b8 100644 --- a/src/main/java/com/loohp/limbo/permissions/PermissionsManager.java +++ b/src/main/java/com/loohp/limbo/permissions/PermissionsManager.java @@ -1,5 +1,10 @@ package com.loohp.limbo.permissions; +import com.loohp.limbo.Console; +import com.loohp.limbo.commands.CommandSender; +import com.loohp.limbo.file.FileConfiguration; +import com.loohp.limbo.player.Player; + import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -7,63 +12,60 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import com.loohp.limbo.Console; -import com.loohp.limbo.commands.CommandSender; -import com.loohp.limbo.file.FileConfiguration; -import com.loohp.limbo.player.Player; - public class PermissionsManager { - - private Map> users; - private Map> permissions; - - public PermissionsManager() { - users = new HashMap<>(); - permissions = new HashMap<>(); - } - - @SuppressWarnings("unchecked") - public void loadDefaultPermissionFile(File file) throws IOException { - FileConfiguration config = new FileConfiguration(file); - permissions.put("default", new ArrayList<>()); - try { - for (Object obj : config.get("groups", Map.class).keySet()) { - String key = (String) obj; - List nodes = new ArrayList<>(); - nodes.addAll(config.get("groups." + key, List.class)); - permissions.put(key, nodes); - } - } catch (Exception e) {} - try { - for (Object obj : config.get("players", Map.class).keySet()) { - String key = (String) obj; - List groups = new ArrayList<>(); - groups.addAll(config.get("players." + key, List.class)); - users.put(key, groups); - } - } catch (Exception e) {} - } - - public boolean hasPermission(CommandSender sender, String permission) { - if (sender instanceof Console) { - return true; - } else if (sender instanceof Player) { - Player player = (Player) sender; - if (users.get(player.getName()) != null && users.get(player.getName()).stream().anyMatch(each -> permissions.get(each).stream().anyMatch(node -> node.equalsIgnoreCase(permission)))) { - return true; - } else { - return permissions.get("default").stream().anyMatch(node -> node.equalsIgnoreCase(permission)); - } - } - return false; - } - public Map> getUsers() { - return users; - } + private final Map> users; + private final Map> permissions; - public Map> getPermissions() { - return permissions; - } + public PermissionsManager() { + users = new HashMap<>(); + permissions = new HashMap<>(); + } + + @SuppressWarnings("unchecked") + public void loadDefaultPermissionFile(File file) throws IOException { + FileConfiguration config = new FileConfiguration(file); + permissions.put("default", new ArrayList<>()); + try { + for (Object obj : config.get("groups", Map.class).keySet()) { + String key = (String) obj; + List nodes = new ArrayList<>(); + nodes.addAll(config.get("groups." + key, List.class)); + permissions.put(key, nodes); + } + } catch (Exception e) { + } + try { + for (Object obj : config.get("players", Map.class).keySet()) { + String key = (String) obj; + List groups = new ArrayList<>(); + groups.addAll(config.get("players." + key, List.class)); + users.put(key, groups); + } + } catch (Exception e) { + } + } + + public boolean hasPermission(CommandSender sender, String permission) { + if (sender instanceof Console) { + return true; + } else if (sender instanceof Player) { + Player player = (Player) sender; + if (users.get(player.getName()) != null && users.get(player.getName()).stream().anyMatch(each -> permissions.get(each).stream().anyMatch(node -> node.equalsIgnoreCase(permission)))) { + return true; + } else { + return permissions.get("default").stream().anyMatch(node -> node.equalsIgnoreCase(permission)); + } + } + return false; + } + + public Map> getUsers() { + return users; + } + + public Map> getPermissions() { + return permissions; + } } diff --git a/src/main/java/com/loohp/limbo/player/Player.java b/src/main/java/com/loohp/limbo/player/Player.java index b634bcc..baba5df 100644 --- a/src/main/java/com/loohp/limbo/player/Player.java +++ b/src/main/java/com/loohp/limbo/player/Player.java @@ -1,147 +1,142 @@ package com.loohp.limbo.player; -import java.io.IOException; -import java.util.UUID; - import com.loohp.limbo.Limbo; -import com.loohp.limbo.events.player.PlayerChatEvent; -import com.loohp.limbo.events.player.PlayerTeleportEvent; -import com.loohp.limbo.server.ClientConnection; -import com.loohp.limbo.server.packets.PacketPlayOutChat; -import com.loohp.limbo.server.packets.PacketPlayOutGameState; -import com.loohp.limbo.server.packets.PacketPlayOutHeldItemChange; -import com.loohp.limbo.server.packets.PacketPlayOutPositionAndLook; -import com.loohp.limbo.server.packets.PacketPlayOutRespawn; import com.loohp.limbo.commands.CommandSender; import com.loohp.limbo.entity.DataWatcher; -import com.loohp.limbo.entity.EntityType; -import com.loohp.limbo.entity.LivingEntity; import com.loohp.limbo.entity.DataWatcher.WatchableField; import com.loohp.limbo.entity.DataWatcher.WatchableObjectType; +import com.loohp.limbo.entity.EntityType; +import com.loohp.limbo.entity.LivingEntity; +import com.loohp.limbo.events.player.PlayerChatEvent; +import com.loohp.limbo.events.player.PlayerTeleportEvent; import com.loohp.limbo.location.Location; +import com.loohp.limbo.server.ClientConnection; +import com.loohp.limbo.server.packets.*; import com.loohp.limbo.utils.GameMode; - import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.chat.ComponentSerializer; +import java.io.IOException; +import java.util.UUID; + public class Player extends LivingEntity implements CommandSender { - public final ClientConnection clientConnection; - public final PlayerInteractManager playerInteractManager; + public final ClientConnection clientConnection; + public final PlayerInteractManager playerInteractManager; - protected final String username; - protected GameMode gamemode; - protected DataWatcher watcher; - protected byte selectedSlot; - - @WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.FLOAT) - protected float additionalHearts = 0.0F; - @WatchableField(MetadataIndex = 15, WatchableObjectType = WatchableObjectType.VARINT) - protected int score = 0; - @WatchableField(MetadataIndex = 16, WatchableObjectType = WatchableObjectType.BYTE) - protected byte skinLayers = 0; - @WatchableField(MetadataIndex = 17, WatchableObjectType = WatchableObjectType.BYTE) - protected byte mainHand = 1; - //@WatchableField(MetadataIndex = 18, WatchableObjectType = WatchableObjectType.NBT) - //protected Entity leftShoulder = null; - //@WatchableField(MetadataIndex = 19, WatchableObjectType = WatchableObjectType.NBT) - //protected Entity rightShoulder = null; - - public Player(ClientConnection clientConnection, String username, UUID uuid, int entityId, Location location, PlayerInteractManager playerInteractManager) throws IllegalArgumentException, IllegalAccessException { - super(EntityType.PLAYER, entityId, uuid, location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); - this.clientConnection = clientConnection; - this.username = username; - this.entityId = entityId; - this.playerInteractManager = playerInteractManager; - this.playerInteractManager.setPlayer(this); - this.watcher = new DataWatcher(this); - this.watcher.update(); - } + protected final String username; + protected GameMode gamemode; + protected DataWatcher watcher; + protected byte selectedSlot; - public byte getSelectedSlot() { - return selectedSlot; - } + @WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.FLOAT) + protected float additionalHearts = 0.0F; + @WatchableField(MetadataIndex = 15, WatchableObjectType = WatchableObjectType.VARINT) + protected int score = 0; + @WatchableField(MetadataIndex = 16, WatchableObjectType = WatchableObjectType.BYTE) + protected byte skinLayers = 0; + @WatchableField(MetadataIndex = 17, WatchableObjectType = WatchableObjectType.BYTE) + protected byte mainHand = 1; + //@WatchableField(MetadataIndex = 18, WatchableObjectType = WatchableObjectType.NBT) + //protected Entity leftShoulder = null; + //@WatchableField(MetadataIndex = 19, WatchableObjectType = WatchableObjectType.NBT) + //protected Entity rightShoulder = null; - public void setSelectedSlot(byte slot) { - if(slot == selectedSlot) - return; - try { - PacketPlayOutHeldItemChange state = new PacketPlayOutHeldItemChange(slot); - clientConnection.sendPacket(state); - } catch (IOException e) { - e.printStackTrace(); - } - this.selectedSlot = slot; - } + public Player(ClientConnection clientConnection, String username, UUID uuid, int entityId, Location location, PlayerInteractManager playerInteractManager) throws IllegalArgumentException, IllegalAccessException { + super(EntityType.PLAYER, entityId, uuid, location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + this.clientConnection = clientConnection; + this.username = username; + this.entityId = entityId; + this.playerInteractManager = playerInteractManager; + this.playerInteractManager.setPlayer(this); + this.watcher = new DataWatcher(this); + this.watcher.update(); + } - public GameMode getGamemode() { - return gamemode; - } + public byte getSelectedSlot() { + return selectedSlot; + } - public void setGamemode(GameMode gamemode) { - if (!this.gamemode.equals(gamemode)) { - try { - PacketPlayOutGameState state = new PacketPlayOutGameState(3, gamemode.getId()); - clientConnection.sendPacket(state); - } catch (IOException e) { - e.printStackTrace(); - } - } - this.gamemode = gamemode; - } - - @Deprecated - protected void setEntityId(int entityId) { - this.entityId = entityId; - } + public void setSelectedSlot(byte slot) { + if (slot == selectedSlot) + return; + try { + PacketPlayOutHeldItemChange state = new PacketPlayOutHeldItemChange(slot); + clientConnection.sendPacket(state); + } catch (IOException e) { + e.printStackTrace(); + } + this.selectedSlot = slot; + } - public float getAdditionalHearts() { - return additionalHearts; - } + public GameMode getGamemode() { + return gamemode; + } - public void setAdditionalHearts(float additionalHearts) { - this.additionalHearts = additionalHearts; - } + public void setGamemode(GameMode gamemode) { + if (!this.gamemode.equals(gamemode)) { + try { + PacketPlayOutGameState state = new PacketPlayOutGameState(3, gamemode.getId()); + clientConnection.sendPacket(state); + } catch (IOException e) { + e.printStackTrace(); + } + } + this.gamemode = gamemode; + } - public int getScore() { - return score; - } + @Deprecated + protected void setEntityId(int entityId) { + this.entityId = entityId; + } - public void setScore(int score) { - this.score = score; - } + public float getAdditionalHearts() { + return additionalHearts; + } - public byte getSkinLayers() { - return skinLayers; - } + public void setAdditionalHearts(float additionalHearts) { + this.additionalHearts = additionalHearts; + } - public void setSkinLayers(byte skinLayers) { - this.skinLayers = skinLayers; - } + public int getScore() { + return score; + } - public byte getMainHand() { - return mainHand; - } + public void setScore(int score) { + this.score = score; + } - public void setMainHand(byte mainHand) { - this.mainHand = mainHand; - } - - @Override - public DataWatcher getDataWatcher() { - return watcher; - } - - @Override - public boolean isValid() { - return Limbo.getInstance().getPlayers().contains(this); - } - - @Override - public void remove() { - - } + public byte getSkinLayers() { + return skinLayers; + } + + public void setSkinLayers(byte skinLayers) { + this.skinLayers = skinLayers; + } + + public byte getMainHand() { + return mainHand; + } + + public void setMainHand(byte mainHand) { + this.mainHand = mainHand; + } + + @Override + public DataWatcher getDataWatcher() { + return watcher; + } + + @Override + public boolean isValid() { + return Limbo.getInstance().getPlayers().contains(this); + } + + @Override + public void remove() { + + } /* public Entity getLeftShoulder() { @@ -161,101 +156,101 @@ public class Player extends LivingEntity implements CommandSender { } */ - @Override - public String getName() { - return username; - } - - @Override - public boolean hasPermission(String permission) { - return Limbo.getInstance().getPermissionsManager().hasPermission(this, permission); - } + @Override + public String getName() { + return username; + } - @Override - public void teleport(Location location) { - PlayerTeleportEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerTeleportEvent(this, getLocation(), location)); - if (!event.isCancelled()) { - location = event.getTo(); - super.teleport(location); - try { - if (!world.equals(location.getWorld())) { - PacketPlayOutRespawn respawn = new PacketPlayOutRespawn(location.getWorld(), Limbo.getInstance().getDimensionRegistry().getCodec(), 0, gamemode, false, false, true); - clientConnection.sendPacket(respawn); - } - PacketPlayOutPositionAndLook positionLook = new PacketPlayOutPositionAndLook(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch(), 1); - clientConnection.sendPacket(positionLook); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - protected void setLocation(Location location) { - super.teleport(location); - } - - public void sendMessage(String message, UUID uuid) { - sendMessage(TextComponent.fromLegacyText(message), uuid); - } + @Override + public boolean hasPermission(String permission) { + return Limbo.getInstance().getPermissionsManager().hasPermission(this, permission); + } - public void sendMessage(BaseComponent component, UUID uuid) { - sendMessage(new BaseComponent[] { component }, uuid); - } + @Override + public void teleport(Location location) { + PlayerTeleportEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerTeleportEvent(this, getLocation(), location)); + if (!event.isCancelled()) { + location = event.getTo(); + super.teleport(location); + try { + if (!world.equals(location.getWorld())) { + PacketPlayOutRespawn respawn = new PacketPlayOutRespawn(location.getWorld(), Limbo.getInstance().getDimensionRegistry().getCodec(), 0, gamemode, false, false, true); + clientConnection.sendPacket(respawn); + } + PacketPlayOutPositionAndLook positionLook = new PacketPlayOutPositionAndLook(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch(), 1); + clientConnection.sendPacket(positionLook); + } catch (IOException e) { + e.printStackTrace(); + } + } + } - @Override - public void sendMessage(BaseComponent[] component, UUID uuid) { - try { - PacketPlayOutChat chat = new PacketPlayOutChat(ComponentSerializer.toString(component), 0, uuid); - clientConnection.sendPacket(chat); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public void sendMessage(String message) { - sendMessage(TextComponent.fromLegacyText(message)); - } + protected void setLocation(Location location) { + super.teleport(location); + } - public void sendMessage(BaseComponent component) { - sendMessage(new BaseComponent[] { component }); - } + public void sendMessage(String message, UUID uuid) { + sendMessage(TextComponent.fromLegacyText(message), uuid); + } - @Override - public void sendMessage(BaseComponent[] component) { - try { - PacketPlayOutChat chat = new PacketPlayOutChat(ComponentSerializer.toString(component), 0, new UUID(0, 0)); - clientConnection.sendPacket(chat); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public void disconnect() { - disconnect("Disconnected!"); - } - - public void disconnect(String reason) { - disconnect(TextComponent.fromLegacyText(reason)); - } - - public void disconnect(BaseComponent reason) { - disconnect(new BaseComponent[] {reason}); - } - - public void disconnect(BaseComponent[] reason) { - clientConnection.disconnect(reason); - } - - public void chat(String message) { - String prefix = "<" + username + "> "; - PlayerChatEvent event = (PlayerChatEvent) Limbo.getInstance().getEventsManager().callEvent(new PlayerChatEvent(this, prefix, message, false)); - if (!event.isCancelled()) { - String chat = event.getPrefix() + event.getMessage(); - Limbo.getInstance().getConsole().sendMessage(chat); - for (Player each : Limbo.getInstance().getPlayers()) { - each.sendMessage(chat, uuid); - } - } - } + public void sendMessage(BaseComponent component, UUID uuid) { + sendMessage(new BaseComponent[]{component}, uuid); + } + + @Override + public void sendMessage(BaseComponent[] component, UUID uuid) { + try { + PacketPlayOutChat chat = new PacketPlayOutChat(ComponentSerializer.toString(component), 0, uuid); + clientConnection.sendPacket(chat); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void sendMessage(String message) { + sendMessage(TextComponent.fromLegacyText(message)); + } + + public void sendMessage(BaseComponent component) { + sendMessage(new BaseComponent[]{component}); + } + + @Override + public void sendMessage(BaseComponent[] component) { + try { + PacketPlayOutChat chat = new PacketPlayOutChat(ComponentSerializer.toString(component), 0, new UUID(0, 0)); + clientConnection.sendPacket(chat); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void disconnect() { + disconnect("Disconnected!"); + } + + public void disconnect(String reason) { + disconnect(TextComponent.fromLegacyText(reason)); + } + + public void disconnect(BaseComponent reason) { + disconnect(new BaseComponent[]{reason}); + } + + public void disconnect(BaseComponent[] reason) { + clientConnection.disconnect(reason); + } + + public void chat(String message) { + String prefix = "<" + username + "> "; + PlayerChatEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerChatEvent(this, prefix, message, false)); + if (!event.isCancelled()) { + String chat = event.getPrefix() + event.getMessage(); + Limbo.getInstance().getConsole().sendMessage(chat); + for (Player each : Limbo.getInstance().getPlayers()) { + each.sendMessage(chat, uuid); + } + } + } } diff --git a/src/main/java/com/loohp/limbo/player/PlayerInteractManager.java b/src/main/java/com/loohp/limbo/player/PlayerInteractManager.java index eb5c209..f5c957a 100644 --- a/src/main/java/com/loohp/limbo/player/PlayerInteractManager.java +++ b/src/main/java/com/loohp/limbo/player/PlayerInteractManager.java @@ -1,135 +1,123 @@ package com.loohp.limbo.player; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.stream.Collectors; - import com.loohp.limbo.Limbo; -import com.loohp.limbo.server.packets.PacketPlayOutEntityDestroy; -import com.loohp.limbo.server.packets.PacketPlayOutEntityMetadata; -import com.loohp.limbo.server.packets.PacketPlayOutLightUpdate; -import com.loohp.limbo.server.packets.PacketPlayOutMapChunk; -import com.loohp.limbo.server.packets.PacketPlayOutSpawnEntity; -import com.loohp.limbo.server.packets.PacketPlayOutSpawnEntityLiving; -import com.loohp.limbo.server.packets.PacketPlayOutUnloadChunk; import com.loohp.limbo.entity.Entity; import com.loohp.limbo.location.Location; +import com.loohp.limbo.server.packets.*; import com.loohp.limbo.world.World; - import net.querz.mca.Chunk; +import java.io.IOException; +import java.util.*; +import java.util.Map.Entry; +import java.util.stream.Collectors; + public class PlayerInteractManager { - - private Player player; - - private Set entities; - private Map chunks; - - public PlayerInteractManager() { - this.player = null; - this.entities = new HashSet<>(); - this.chunks = new HashMap<>(); - } - - protected void setPlayer(Player player) { - if (this.player == null) { - this.player = player; - } else { - throw new RuntimeException("Player in PlayerInteractManager cannot be changed once created"); - } - } - - public Player getPlayer() { - return player; - } - - public void update() throws IOException { - int viewDistanceChunks = Limbo.getInstance().getServerProperties().getViewDistance(); - int viewDistanceBlocks = viewDistanceChunks << 4; - Location location = player.getLocation(); - Set entitiesInRange = player.getWorld().getEntities().stream().filter(each -> each.getLocation().distanceSquared(location) < viewDistanceBlocks * viewDistanceBlocks).collect(Collectors.toSet()); - for (Entity entity : entitiesInRange) { - if (!entities.contains(entity)) { - if (entity.getType().isAlive()) { - PacketPlayOutSpawnEntityLiving packet = new PacketPlayOutSpawnEntityLiving(entity.getEntityId(), entity.getUniqueId(), entity.getType(), entity.getX(), entity.getY(), entity.getZ(), entity.getYaw(), entity.getPitch(), entity.getPitch(), (short) 0, (short) 0, (short) 0); - player.clientConnection.sendPacket(packet); - - PacketPlayOutEntityMetadata meta = new PacketPlayOutEntityMetadata(entity); - player.clientConnection.sendPacket(meta); - } else { - PacketPlayOutSpawnEntity packet = new PacketPlayOutSpawnEntity(entity.getEntityId(), entity.getUniqueId(), entity.getType(), entity.getX(), entity.getY(), entity.getZ(), entity.getPitch(), entity.getYaw(), (short) 0, (short) 0, (short) 0); - player.clientConnection.sendPacket(packet); - - PacketPlayOutEntityMetadata meta = new PacketPlayOutEntityMetadata(entity); - player.clientConnection.sendPacket(meta); - } - } - } - List ids = new ArrayList<>(); - for (Entity entity : entities) { - if (!entitiesInRange.contains(entity)) { - ids.add(entity.getEntityId()); - } - } - PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(ids.stream().mapToInt(each -> each).toArray()); - player.clientConnection.sendPacket(packet); - - entities = entitiesInRange; - - int playerChunkX = (int) location.getX() >> 4; - int playerChunkZ = (int) location.getZ() >> 4; - World world = location.getWorld(); - - Set chunksInRange = new HashSet<>(); - - for (int x = playerChunkX - viewDistanceChunks; x < playerChunkX + viewDistanceChunks; x++) { - for (int z = playerChunkZ - viewDistanceChunks; z < playerChunkZ + viewDistanceChunks; z++) { - Chunk chunk = world.getChunkAt(x, z); - if (chunk != null) { - chunksInRange.add(chunk); - } - } - } - - for (Entry entry : chunks.entrySet()) { - Chunk chunk = entry.getKey(); - if (location.getWorld().getChunkXZ(chunk) == null) { - World world0 = entry.getValue(); - int[] chunkPos = world0.getChunkXZ(chunk); - PacketPlayOutUnloadChunk packet0 = new PacketPlayOutUnloadChunk(chunkPos[0], chunkPos[1]); - player.clientConnection.sendPacket(packet0); - } - } - - for (Chunk chunk : chunksInRange) { - if (!chunks.containsKey(chunk)) { - int[] chunkPos = world.getChunkXZ(chunk); - PacketPlayOutMapChunk packet0 = new PacketPlayOutMapChunk(chunkPos[0], chunkPos[1], chunk, world.getEnvironment()); - player.clientConnection.sendPacket(packet0); - - List blockChunk = world.getLightEngineBlock().getBlockLightBitMask(chunkPos[0], chunkPos[1]); - if (blockChunk == null) { - blockChunk = new ArrayList<>(); - } - List skyChunk = null; - if (world.hasSkyLight()) { - skyChunk = world.getLightEngineSky().getSkyLightBitMask(chunkPos[0], chunkPos[1]); - } - if (skyChunk == null) { - skyChunk = new ArrayList<>(); - } - PacketPlayOutLightUpdate chunkdata = new PacketPlayOutLightUpdate(chunkPos[0], chunkPos[1], true, skyChunk, blockChunk); - player.clientConnection.sendPacket(chunkdata); - } - } - - chunks = chunksInRange.stream().collect(Collectors.toMap(each -> each, each -> world)); - } + + private Player player; + + private Set entities; + private Map chunks; + + public PlayerInteractManager() { + this.player = null; + this.entities = new HashSet<>(); + this.chunks = new HashMap<>(); + } + + public Player getPlayer() { + return player; + } + + protected void setPlayer(Player player) { + if (this.player == null) { + this.player = player; + } else { + throw new RuntimeException("Player in PlayerInteractManager cannot be changed once created"); + } + } + + public void update() throws IOException { + int viewDistanceChunks = Limbo.getInstance().getServerProperties().getViewDistance(); + int viewDistanceBlocks = viewDistanceChunks << 4; + Location location = player.getLocation(); + Set entitiesInRange = player.getWorld().getEntities().stream().filter(each -> each.getLocation().distanceSquared(location) < viewDistanceBlocks * viewDistanceBlocks).collect(Collectors.toSet()); + for (Entity entity : entitiesInRange) { + if (!entities.contains(entity)) { + if (entity.getType().isAlive()) { + PacketPlayOutSpawnEntityLiving packet = new PacketPlayOutSpawnEntityLiving(entity.getEntityId(), entity.getUniqueId(), entity.getType(), entity.getX(), entity.getY(), entity.getZ(), entity.getYaw(), entity.getPitch(), entity.getPitch(), (short) 0, (short) 0, (short) 0); + player.clientConnection.sendPacket(packet); + + PacketPlayOutEntityMetadata meta = new PacketPlayOutEntityMetadata(entity); + player.clientConnection.sendPacket(meta); + } else { + PacketPlayOutSpawnEntity packet = new PacketPlayOutSpawnEntity(entity.getEntityId(), entity.getUniqueId(), entity.getType(), entity.getX(), entity.getY(), entity.getZ(), entity.getPitch(), entity.getYaw(), (short) 0, (short) 0, (short) 0); + player.clientConnection.sendPacket(packet); + + PacketPlayOutEntityMetadata meta = new PacketPlayOutEntityMetadata(entity); + player.clientConnection.sendPacket(meta); + } + } + } + List ids = new ArrayList<>(); + for (Entity entity : entities) { + if (!entitiesInRange.contains(entity)) { + ids.add(entity.getEntityId()); + } + } + PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(ids.stream().mapToInt(each -> each).toArray()); + player.clientConnection.sendPacket(packet); + + entities = entitiesInRange; + + int playerChunkX = (int) location.getX() >> 4; + int playerChunkZ = (int) location.getZ() >> 4; + World world = location.getWorld(); + + Set chunksInRange = new HashSet<>(); + + for (int x = playerChunkX - viewDistanceChunks; x < playerChunkX + viewDistanceChunks; x++) { + for (int z = playerChunkZ - viewDistanceChunks; z < playerChunkZ + viewDistanceChunks; z++) { + Chunk chunk = world.getChunkAt(x, z); + if (chunk != null) { + chunksInRange.add(chunk); + } + } + } + + for (Entry entry : chunks.entrySet()) { + Chunk chunk = entry.getKey(); + if (location.getWorld().getChunkXZ(chunk) == null) { + World world0 = entry.getValue(); + int[] chunkPos = world0.getChunkXZ(chunk); + PacketPlayOutUnloadChunk packet0 = new PacketPlayOutUnloadChunk(chunkPos[0], chunkPos[1]); + player.clientConnection.sendPacket(packet0); + } + } + + for (Chunk chunk : chunksInRange) { + if (!chunks.containsKey(chunk)) { + int[] chunkPos = world.getChunkXZ(chunk); + PacketPlayOutMapChunk packet0 = new PacketPlayOutMapChunk(chunkPos[0], chunkPos[1], chunk, world.getEnvironment()); + player.clientConnection.sendPacket(packet0); + + List blockChunk = world.getLightEngineBlock().getBlockLightBitMask(chunkPos[0], chunkPos[1]); + if (blockChunk == null) { + blockChunk = new ArrayList<>(); + } + List skyChunk = null; + if (world.hasSkyLight()) { + skyChunk = world.getLightEngineSky().getSkyLightBitMask(chunkPos[0], chunkPos[1]); + } + if (skyChunk == null) { + skyChunk = new ArrayList<>(); + } + PacketPlayOutLightUpdate chunkdata = new PacketPlayOutLightUpdate(chunkPos[0], chunkPos[1], true, skyChunk, blockChunk); + player.clientConnection.sendPacket(chunkdata); + } + } + + chunks = chunksInRange.stream().collect(Collectors.toMap(each -> each, each -> world)); + } } diff --git a/src/main/java/com/loohp/limbo/player/Unsafe.java b/src/main/java/com/loohp/limbo/player/Unsafe.java index 2d5f57d..2a94305 100644 --- a/src/main/java/com/loohp/limbo/player/Unsafe.java +++ b/src/main/java/com/loohp/limbo/player/Unsafe.java @@ -5,27 +5,28 @@ import com.loohp.limbo.utils.GameMode; @Deprecated public class Unsafe { - - private Unsafe() {} - - @Deprecated - public void a(Player a, GameMode b) { - a.gamemode = b; - } - - @Deprecated - public void a(Player a, int b) { - a.setEntityId(b); - } - - @Deprecated - public void a(Player a, Location b) { - a.setLocation(b); - } - @Deprecated - public void a(Player a, byte b) { - a.selectedSlot = b; - } + private Unsafe() { + } + + @Deprecated + public void a(Player a, GameMode b) { + a.gamemode = b; + } + + @Deprecated + public void a(Player a, int b) { + a.setEntityId(b); + } + + @Deprecated + public void a(Player a, Location b) { + a.setLocation(b); + } + + @Deprecated + public void a(Player a, byte b) { + a.selectedSlot = b; + } } diff --git a/src/main/java/com/loohp/limbo/plugins/LimboPlugin.java b/src/main/java/com/loohp/limbo/plugins/LimboPlugin.java index 2a21fb0..fd98601 100644 --- a/src/main/java/com/loohp/limbo/plugins/LimboPlugin.java +++ b/src/main/java/com/loohp/limbo/plugins/LimboPlugin.java @@ -1,54 +1,54 @@ package com.loohp.limbo.plugins; -import java.io.File; - import com.loohp.limbo.Limbo; import com.loohp.limbo.file.FileConfiguration; +import java.io.File; + public class LimboPlugin { - private String name; - private File dataFolder; - private PluginInfo info; - private File pluginJar; - - protected final void setInfo(FileConfiguration file, File pluginJar) { - this.info = new PluginInfo(file); - this.name = info.getName(); - this.dataFolder = new File(Limbo.getInstance().getPluginFolder(), name); - this.pluginJar = pluginJar; - } - - protected final File getPluginJar() { - return pluginJar; - } + private String name; + private File dataFolder; + private PluginInfo info; + private File pluginJar; - public void onLoad() { + protected final void setInfo(FileConfiguration file, File pluginJar) { + this.info = new PluginInfo(file); + this.name = info.getName(); + this.dataFolder = new File(Limbo.getInstance().getPluginFolder(), name); + this.pluginJar = pluginJar; + } - } + protected final File getPluginJar() { + return pluginJar; + } - public void onEnable() { + public void onLoad() { - } + } - public void onDisable() { + public void onEnable() { - } + } - public final String getName() { - return name; - } + public void onDisable() { - public final File getDataFolder() { - return new File(dataFolder.getAbsolutePath()); - } - - public final PluginInfo getInfo() { - return info; - } - - public final Limbo getServer() { - return Limbo.getInstance(); - } + } + + public final String getName() { + return name; + } + + public final File getDataFolder() { + return new File(dataFolder.getAbsolutePath()); + } + + public final PluginInfo getInfo() { + return info; + } + + public final Limbo getServer() { + return Limbo.getInstance(); + } } diff --git a/src/main/java/com/loohp/limbo/plugins/PluginInfo.java b/src/main/java/com/loohp/limbo/plugins/PluginInfo.java index 7766f62..791e9a2 100644 --- a/src/main/java/com/loohp/limbo/plugins/PluginInfo.java +++ b/src/main/java/com/loohp/limbo/plugins/PluginInfo.java @@ -3,39 +3,39 @@ package com.loohp.limbo.plugins; import com.loohp.limbo.file.FileConfiguration; public class PluginInfo { - - private String name; - private String description; - private String author; - private String version; - private String main; - - public PluginInfo(FileConfiguration file) { - name = file.get("name", String.class); - description = file.get("description", String.class) == null ? "" : file.get("description", String.class); - author = file.get("author", String.class); - version = file.get("version", String.class); - main = file.get("main", String.class); - } - public String getName() { - return name; - } + private final String name; + private final String description; + private final String author; + private final String version; + private final String main; - public String getDescription() { - return description; - } - - public String getAuthor() { - return author; - } + public PluginInfo(FileConfiguration file) { + name = file.get("name", String.class); + description = file.get("description", String.class) == null ? "" : file.get("description", String.class); + author = file.get("author", String.class); + version = file.get("version", String.class); + main = file.get("main", String.class); + } - public String getVersion() { - return version; - } + public String getName() { + return name; + } - public String getMainClass() { - return main; - } + public String getDescription() { + return description; + } + + public String getAuthor() { + return author; + } + + public String getVersion() { + return version; + } + + public String getMainClass() { + return main; + } } diff --git a/src/main/java/com/loohp/limbo/plugins/PluginManager.java b/src/main/java/com/loohp/limbo/plugins/PluginManager.java index 462419c..0cc3ce2 100644 --- a/src/main/java/com/loohp/limbo/plugins/PluginManager.java +++ b/src/main/java/com/loohp/limbo/plugins/PluginManager.java @@ -1,139 +1,135 @@ package com.loohp.limbo.plugins; -import java.io.File; -import java.io.FileInputStream; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - import com.loohp.limbo.Limbo; import com.loohp.limbo.commands.CommandExecutor; import com.loohp.limbo.commands.CommandSender; import com.loohp.limbo.commands.TabCompletor; import com.loohp.limbo.file.FileConfiguration; +import java.io.File; +import java.io.FileInputStream; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.*; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + public class PluginManager { - private Map plugins; - private List executors; - private File pluginFolder; + private final Map plugins; + private final List executors; + private final File pluginFolder; - public PluginManager(File pluginFolder) { - this.pluginFolder = pluginFolder; - this.executors = new ArrayList<>(); - this.plugins = new LinkedHashMap<>(); - } - - protected void loadPlugins() { - for (File file : pluginFolder.listFiles()) { - if (file.isFile() && file.getName().endsWith(".jar")) { - boolean found = false; - try (ZipInputStream zip = new ZipInputStream(new FileInputStream(file))) { - while (true) { - ZipEntry entry = zip.getNextEntry(); - if (entry == null) { - break; - } - String name = entry.getName(); - if (name.endsWith("plugin.yml") || name.endsWith("limbo.yml")) { - found = true; - - FileConfiguration pluginYaml = new FileConfiguration(zip); - String main = pluginYaml.get("main", String.class); - String pluginName = pluginYaml.get("name", String.class); - - if (plugins.containsKey(pluginName)) { - System.err.println("Ambiguous plugin name in " + file.getName() + " with the plugin \"" + plugins.get(pluginName).getClass().getName() + "\""); - break; - } - URLClassLoader child = new URLClassLoader(new URL[] {file.toURI().toURL()}, Limbo.getInstance().getClass().getClassLoader()); - Class clazz = Class.forName(main, true, child); - LimboPlugin plugin = (LimboPlugin) clazz.getDeclaredConstructor().newInstance(); - plugin.setInfo(pluginYaml, file); - plugins.put(plugin.getName(), plugin); - plugin.onLoad(); - Limbo.getInstance().getConsole().sendMessage("Loading plugin " + file.getName() + " " + plugin.getInfo().getVersion() + " by " + plugin.getInfo().getAuthor()); - break; - } - } - } catch (Exception e) { - System.err.println("Unable to load plugin \"" + file.getName() + "\""); - e.printStackTrace(); - } - if (!found) { - System.err.println("Jar file " + file.getName() + " has no plugin.yml!"); - } - } - } - } - - public List getPlugins() { - return new ArrayList<>(plugins.values()); - } - - public LimboPlugin getPlugin(String name) { - return plugins.get(name); - } + public PluginManager(File pluginFolder) { + this.pluginFolder = pluginFolder; + this.executors = new ArrayList<>(); + this.plugins = new LinkedHashMap<>(); + } - public void fireExecutors(CommandSender sender, String[] args) throws Exception { - Limbo.getInstance().getConsole().sendMessage(sender.getName() + " executed server command: /" + String.join(" ", args)); - for (Executor entry : executors) { - try { - entry.executor.execute(sender, args); - } catch (Exception e) { - System.err.println("Error while passing command \"" + args[0] + "\" to the plugin \"" + entry.plugin.getName() + "\""); - e.printStackTrace(); - } - } - } + protected void loadPlugins() { + for (File file : pluginFolder.listFiles()) { + if (file.isFile() && file.getName().endsWith(".jar")) { + boolean found = false; + try (ZipInputStream zip = new ZipInputStream(new FileInputStream(file))) { + while (true) { + ZipEntry entry = zip.getNextEntry(); + if (entry == null) { + break; + } + String name = entry.getName(); + if (name.endsWith("plugin.yml") || name.endsWith("limbo.yml")) { + found = true; - public List getTabOptions(CommandSender sender, String[] args) { - List options = new ArrayList<>(); - for (Executor entry : executors) { - if (entry.tab.isPresent()) { - try { - options.addAll(entry.tab.get().tabComplete(sender, args)); - } catch (Exception e) { - System.err.println("Error while passing tab completion to the plugin \"" + entry.plugin.getName() + "\""); - e.printStackTrace(); - } - } - } - return options; - } + FileConfiguration pluginYaml = new FileConfiguration(zip); + String main = pluginYaml.get("main", String.class); + String pluginName = pluginYaml.get("name", String.class); - public void registerCommands(LimboPlugin plugin, CommandExecutor executor) { - executors.add(new Executor(plugin, executor)); - } + if (plugins.containsKey(pluginName)) { + System.err.println("Ambiguous plugin name in " + file.getName() + " with the plugin \"" + plugins.get(pluginName).getClass().getName() + "\""); + break; + } + URLClassLoader child = new URLClassLoader(new URL[]{file.toURI().toURL()}, Limbo.getInstance().getClass().getClassLoader()); + Class clazz = Class.forName(main, true, child); + LimboPlugin plugin = (LimboPlugin) clazz.getDeclaredConstructor().newInstance(); + plugin.setInfo(pluginYaml, file); + plugins.put(plugin.getName(), plugin); + plugin.onLoad(); + Limbo.getInstance().getConsole().sendMessage("Loading plugin " + file.getName() + " " + plugin.getInfo().getVersion() + " by " + plugin.getInfo().getAuthor()); + break; + } + } + } catch (Exception e) { + System.err.println("Unable to load plugin \"" + file.getName() + "\""); + e.printStackTrace(); + } + if (!found) { + System.err.println("Jar file " + file.getName() + " has no plugin.yml!"); + } + } + } + } - public void unregsiterAllCommands(LimboPlugin plugin) { - executors.removeIf(each -> each.plugin.equals(plugin)); - } - - public File getPluginFolder() { - return new File(pluginFolder.getAbsolutePath()); - } + public List getPlugins() { + return new ArrayList<>(plugins.values()); + } - protected static class Executor { - public LimboPlugin plugin; - public CommandExecutor executor; - public Optional tab; + public LimboPlugin getPlugin(String name) { + return plugins.get(name); + } - public Executor(LimboPlugin plugin, CommandExecutor executor) { - this.plugin = plugin; - this.executor = executor; - if (executor instanceof TabCompletor) { - this.tab = Optional.of((TabCompletor) executor); - } else { - this.tab = Optional.empty(); - } - } - } + public void fireExecutors(CommandSender sender, String[] args) throws Exception { + Limbo.getInstance().getConsole().sendMessage(sender.getName() + " executed server command: /" + String.join(" ", args)); + for (Executor entry : executors) { + try { + entry.executor.execute(sender, args); + } catch (Exception e) { + System.err.println("Error while passing command \"" + args[0] + "\" to the plugin \"" + entry.plugin.getName() + "\""); + e.printStackTrace(); + } + } + } + + public List getTabOptions(CommandSender sender, String[] args) { + List options = new ArrayList<>(); + for (Executor entry : executors) { + if (entry.tab.isPresent()) { + try { + options.addAll(entry.tab.get().tabComplete(sender, args)); + } catch (Exception e) { + System.err.println("Error while passing tab completion to the plugin \"" + entry.plugin.getName() + "\""); + e.printStackTrace(); + } + } + } + return options; + } + + public void registerCommands(LimboPlugin plugin, CommandExecutor executor) { + executors.add(new Executor(plugin, executor)); + } + + public void unregsiterAllCommands(LimboPlugin plugin) { + executors.removeIf(each -> each.plugin.equals(plugin)); + } + + public File getPluginFolder() { + return new File(pluginFolder.getAbsolutePath()); + } + + protected static class Executor { + public LimboPlugin plugin; + public CommandExecutor executor; + public Optional tab; + + public Executor(LimboPlugin plugin, CommandExecutor executor) { + this.plugin = plugin; + this.executor = executor; + if (executor instanceof TabCompletor) { + this.tab = Optional.of((TabCompletor) executor); + } else { + this.tab = Optional.empty(); + } + } + } } diff --git a/src/main/java/com/loohp/limbo/scheduler/LimboRunnable.java b/src/main/java/com/loohp/limbo/scheduler/LimboRunnable.java index 39d85ff..eb09a13 100644 --- a/src/main/java/com/loohp/limbo/scheduler/LimboRunnable.java +++ b/src/main/java/com/loohp/limbo/scheduler/LimboRunnable.java @@ -4,96 +4,96 @@ import com.loohp.limbo.Limbo; import com.loohp.limbo.plugins.LimboPlugin; public abstract class LimboRunnable implements LimboTask { - - private volatile boolean registered = false; - protected volatile int taskId = -1; - - public void cancel() { - synchronized (this) { - if (registered && taskId >= 0) { - Limbo.getInstance().getScheduler().cancelTask(taskId); - } - } - } - - public int getTaskId() { - if (registered && taskId >= 0) { - return taskId; - } else { - throw new IllegalStateException("LimboRunnable not yet scheduled"); - } - } - - public LimboRunnable runTask(LimboPlugin plugin) { - synchronized (this) { - if (!registered) { - taskId = Limbo.getInstance().getScheduler().runTask(plugin, this); - registered = true; - return this; - } else { - throw new IllegalStateException("LimboRunnable already scheduled"); - } - } - } - - public LimboRunnable runTaskLater(LimboPlugin plugin, long delay) { - synchronized (this) { - if (!registered) { - taskId = Limbo.getInstance().getScheduler().runTaskLater(plugin, this, delay); - registered = true; - return this; - } else { - throw new IllegalStateException("LimboRunnable already scheduled"); - } - } - } - - public LimboRunnable runTaskAsync(LimboPlugin plugin) { - synchronized (this) { - if (!registered) { - taskId = Limbo.getInstance().getScheduler().runTaskAsync(plugin, this); - registered = true; - return this; - } else { - throw new IllegalStateException("LimboRunnable already scheduled"); - } - } - } - - public LimboRunnable runTaskLaterAsync(LimboPlugin plugin, long delay) { - synchronized (this) { - if (!registered) { - taskId = Limbo.getInstance().getScheduler().runTaskLaterAsync(plugin, this, delay); - registered = true; - return this; - } else { - throw new IllegalStateException("LimboRunnable already scheduled"); - } - } - } - - public LimboRunnable runTaskTimer(LimboPlugin plugin, long delay, long period) { - synchronized (this) { - if (!registered) { - taskId = Limbo.getInstance().getScheduler().runTaskTimer(plugin, this, delay, period); - registered = true; - return this; - } else { - throw new IllegalStateException("LimboRunnable already scheduled"); - } - } - } - - public LimboRunnable runTaskTimerAsync(LimboPlugin plugin, long delay, long period) { - synchronized (this) { - if (!registered) { - taskId = Limbo.getInstance().getScheduler().runTaskTimerAsync(plugin, this, delay, period); - registered = true; - return this; - } else { - throw new IllegalStateException("LimboRunnable already scheduled"); - } - } - } + + protected volatile int taskId = -1; + private volatile boolean registered = false; + + public void cancel() { + synchronized (this) { + if (registered && taskId >= 0) { + Limbo.getInstance().getScheduler().cancelTask(taskId); + } + } + } + + public int getTaskId() { + if (registered && taskId >= 0) { + return taskId; + } else { + throw new IllegalStateException("LimboRunnable not yet scheduled"); + } + } + + public LimboRunnable runTask(LimboPlugin plugin) { + synchronized (this) { + if (!registered) { + taskId = Limbo.getInstance().getScheduler().runTask(plugin, this); + registered = true; + return this; + } else { + throw new IllegalStateException("LimboRunnable already scheduled"); + } + } + } + + public LimboRunnable runTaskLater(LimboPlugin plugin, long delay) { + synchronized (this) { + if (!registered) { + taskId = Limbo.getInstance().getScheduler().runTaskLater(plugin, this, delay); + registered = true; + return this; + } else { + throw new IllegalStateException("LimboRunnable already scheduled"); + } + } + } + + public LimboRunnable runTaskAsync(LimboPlugin plugin) { + synchronized (this) { + if (!registered) { + taskId = Limbo.getInstance().getScheduler().runTaskAsync(plugin, this); + registered = true; + return this; + } else { + throw new IllegalStateException("LimboRunnable already scheduled"); + } + } + } + + public LimboRunnable runTaskLaterAsync(LimboPlugin plugin, long delay) { + synchronized (this) { + if (!registered) { + taskId = Limbo.getInstance().getScheduler().runTaskLaterAsync(plugin, this, delay); + registered = true; + return this; + } else { + throw new IllegalStateException("LimboRunnable already scheduled"); + } + } + } + + public LimboRunnable runTaskTimer(LimboPlugin plugin, long delay, long period) { + synchronized (this) { + if (!registered) { + taskId = Limbo.getInstance().getScheduler().runTaskTimer(plugin, this, delay, period); + registered = true; + return this; + } else { + throw new IllegalStateException("LimboRunnable already scheduled"); + } + } + } + + public LimboRunnable runTaskTimerAsync(LimboPlugin plugin, long delay, long period) { + synchronized (this) { + if (!registered) { + taskId = Limbo.getInstance().getScheduler().runTaskTimerAsync(plugin, this, delay, period); + registered = true; + return this; + } else { + throw new IllegalStateException("LimboRunnable already scheduled"); + } + } + } } diff --git a/src/main/java/com/loohp/limbo/scheduler/LimboScheduler.java b/src/main/java/com/loohp/limbo/scheduler/LimboScheduler.java index 1db80f1..2f30ad9 100644 --- a/src/main/java/com/loohp/limbo/scheduler/LimboScheduler.java +++ b/src/main/java/com/loohp/limbo/scheduler/LimboScheduler.java @@ -1,250 +1,244 @@ package com.loohp.limbo.scheduler; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; - import com.loohp.limbo.Limbo; import com.loohp.limbo.plugins.LimboPlugin; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; + public class LimboScheduler { - - private AtomicInteger idProvider = new AtomicInteger(0); - private Map> registeredTasks = new HashMap<>(); - private Map tasksById = new HashMap<>(); - private Set cancelledTasks = new HashSet<>(); - - public LimboScheduler() { - - } - - protected int nextId() { - return idProvider.getAndUpdate(id -> id >= Integer.MAX_VALUE ? 0 : id + 1); - } - - public void cancelTask(int taskId) { - if (tasksById.containsKey(taskId)) { - cancelledTasks.add(taskId); - } - } - - public void cancelTask(LimboPlugin plugin) { - for (LimboSchedulerTask task : tasksById.values()) { - if (task.getPlugin().getName().equals(plugin.getName())) { - cancelledTasks.add(task.getTaskId()); - } - } - } - - protected int runTask(int taskId, LimboPlugin plugin, LimboTask task) { - return runTaskLater(taskId, plugin, task, 0); - } - - public int runTask(LimboPlugin plugin, LimboTask task) { - return runTaskLater(plugin, task, 0); - } - - protected int runTaskLater(int taskId, LimboPlugin plugin, LimboTask task, long delay) { - LimboSchedulerTask st = new LimboSchedulerTask(plugin, task, taskId, LimboSchedulerTaskType.SYNC, 0); - if (delay <= 0) { - delay = 1; - } - long tick = Limbo.getInstance().getHeartBeat().getCurrentTick() + delay; - tasksById.put(taskId, st); - List list = registeredTasks.get(tick); - if (list == null) { - list = new ArrayList<>(); - registeredTasks.put(tick, list); - } - list.add(st); - return taskId; - } - - public int runTaskLater(LimboPlugin plugin, LimboTask task, long delay) { - return runTaskLater(nextId(), plugin, task, delay); - } - - protected int runTaskAsync(int taskId, LimboPlugin plugin, LimboTask task) { - return runTaskLaterAsync(taskId, plugin, task, 0); - } - - public int runTaskAsync(LimboPlugin plugin, LimboTask task) { - return runTaskLaterAsync(plugin, task, 0); - } - - protected int runTaskLaterAsync(int taskId, LimboPlugin plugin, LimboTask task, long delay) { - LimboSchedulerTask st = new LimboSchedulerTask(plugin, task, taskId, LimboSchedulerTaskType.ASYNC, 0); - if (delay <= 0) { - delay = 1; - } - long tick = Limbo.getInstance().getHeartBeat().getCurrentTick() + delay; - tasksById.put(taskId, st); - List list = registeredTasks.get(tick); - if (list == null) { - list = new ArrayList<>(); - registeredTasks.put(tick, list); - } - list.add(st); - return taskId; - } - - public int runTaskLaterAsync(LimboPlugin plugin, LimboTask task, long delay) { - return runTaskLaterAsync(nextId(), plugin, task, delay); - } - - protected int runTaskTimer(int taskId, LimboPlugin plugin, LimboTask task, long delay, long period) { - LimboSchedulerTask st = new LimboSchedulerTask(plugin, task, taskId, LimboSchedulerTaskType.TIMER_SYNC, period); - if (delay <= 0) { - delay = 1; - } - if (period <= 0) { - period = 1; - } - long tick = Limbo.getInstance().getHeartBeat().getCurrentTick() + delay; - tasksById.put(taskId, st); - List list = registeredTasks.get(tick); - if (list == null) { - list = new ArrayList<>(); - registeredTasks.put(tick, list); - } - list.add(st); - return taskId; - } - - public int runTaskTimer(LimboPlugin plugin, LimboTask task, long delay, long period) { - return runTaskTimer(nextId(), plugin, task, delay, period); - } - - protected int runTaskTimerAsync(int taskId, LimboPlugin plugin, LimboTask task, long delay, long period) { - LimboSchedulerTask st = new LimboSchedulerTask(plugin, task, taskId, LimboSchedulerTaskType.TIMER_ASYNC, period); - if (delay <= 0) { - delay = 1; - } - if (period <= 0) { - period = 1; - } - long tick = Limbo.getInstance().getHeartBeat().getCurrentTick() + delay; - tasksById.put(taskId, st); - List list = registeredTasks.get(tick); - if (list == null) { - list = new ArrayList<>(); - registeredTasks.put(tick, list); - } - list.add(st); - return taskId; - } - - public int runTaskTimerAsync(LimboPlugin plugin, LimboTask task, long delay, long period) { - return runTaskTimerAsync(nextId(), plugin, task, delay, period); - } - - protected CurrentSchedulerTask collectTasks(long currentTick) { - List tasks = registeredTasks.remove(currentTick); - if (tasks == null) { - return null; - } - - List asyncTasks = new LinkedList<>(); - List syncedTasks = new LinkedList<>(); - - for (LimboSchedulerTask task : tasks) { - int taskId = task.getTaskId(); - if (cancelledTasks.contains(taskId)) { - cancelledTasks.remove(taskId); - continue; - } - - switch (task.getType()) { - case ASYNC: - asyncTasks.add(task); - break; - case SYNC: - syncedTasks.add(task); - break; - case TIMER_ASYNC: - asyncTasks.add(task); - runTaskTimerAsync(task.getTaskId(), task.getPlugin(), task.getTask(), task.getPeriod(), task.getPeriod()); - break; - case TIMER_SYNC: - syncedTasks.add(task); - runTaskTimer(task.getTaskId(), task.getPlugin(), task.getTask(), task.getPeriod(), task.getPeriod()); - break; - } - } - - return new CurrentSchedulerTask(syncedTasks, asyncTasks); - } - - public static class CurrentSchedulerTask { - - private List asyncTasks; - private List syncedTasks; - - public CurrentSchedulerTask(List syncedTasks, List asyncTasks) { - this.asyncTasks = asyncTasks; - this.syncedTasks = syncedTasks; - } - public List getAsyncTasks() { - return asyncTasks; - } + private final AtomicInteger idProvider = new AtomicInteger(0); + private final Map> registeredTasks = new HashMap<>(); + private final Map tasksById = new HashMap<>(); + private final Set cancelledTasks = new HashSet<>(); - public List getSyncedTasks() { - return syncedTasks; - } - - } - - public static class LimboSchedulerTask { - - private int taskId; - private LimboPlugin plugin; - private LimboTask task; - private LimboSchedulerTaskType type; - private long period; - - private LimboSchedulerTask(LimboPlugin plugin, LimboTask task, int taskId, LimboSchedulerTaskType type, long period) { - this.plugin = plugin; - this.task = task; - this.taskId = taskId; - this.type = type; - this.period = period; - } - - public LimboPlugin getPlugin() { - return plugin; - } - - public LimboTask getTask() { - return task; - } - - public int getTaskId() { - return taskId; - } - - public LimboSchedulerTaskType getType() { - return type; - } - - public long getPeriod() { - return period; - } - - } - - public static enum LimboSchedulerTaskType { - - SYNC, - ASYNC, - TIMER_SYNC, - TIMER_ASYNC; - - } + public LimboScheduler() { + + } + + protected int nextId() { + return idProvider.getAndUpdate(id -> id >= Integer.MAX_VALUE ? 0 : id + 1); + } + + public void cancelTask(int taskId) { + if (tasksById.containsKey(taskId)) { + cancelledTasks.add(taskId); + } + } + + public void cancelTask(LimboPlugin plugin) { + for (LimboSchedulerTask task : tasksById.values()) { + if (task.getPlugin().getName().equals(plugin.getName())) { + cancelledTasks.add(task.getTaskId()); + } + } + } + + protected int runTask(int taskId, LimboPlugin plugin, LimboTask task) { + return runTaskLater(taskId, plugin, task, 0); + } + + public int runTask(LimboPlugin plugin, LimboTask task) { + return runTaskLater(plugin, task, 0); + } + + protected int runTaskLater(int taskId, LimboPlugin plugin, LimboTask task, long delay) { + LimboSchedulerTask st = new LimboSchedulerTask(plugin, task, taskId, LimboSchedulerTaskType.SYNC, 0); + if (delay <= 0) { + delay = 1; + } + long tick = Limbo.getInstance().getHeartBeat().getCurrentTick() + delay; + tasksById.put(taskId, st); + List list = registeredTasks.get(tick); + if (list == null) { + list = new ArrayList<>(); + registeredTasks.put(tick, list); + } + list.add(st); + return taskId; + } + + public int runTaskLater(LimboPlugin plugin, LimboTask task, long delay) { + return runTaskLater(nextId(), plugin, task, delay); + } + + protected int runTaskAsync(int taskId, LimboPlugin plugin, LimboTask task) { + return runTaskLaterAsync(taskId, plugin, task, 0); + } + + public int runTaskAsync(LimboPlugin plugin, LimboTask task) { + return runTaskLaterAsync(plugin, task, 0); + } + + protected int runTaskLaterAsync(int taskId, LimboPlugin plugin, LimboTask task, long delay) { + LimboSchedulerTask st = new LimboSchedulerTask(plugin, task, taskId, LimboSchedulerTaskType.ASYNC, 0); + if (delay <= 0) { + delay = 1; + } + long tick = Limbo.getInstance().getHeartBeat().getCurrentTick() + delay; + tasksById.put(taskId, st); + List list = registeredTasks.get(tick); + if (list == null) { + list = new ArrayList<>(); + registeredTasks.put(tick, list); + } + list.add(st); + return taskId; + } + + public int runTaskLaterAsync(LimboPlugin plugin, LimboTask task, long delay) { + return runTaskLaterAsync(nextId(), plugin, task, delay); + } + + protected int runTaskTimer(int taskId, LimboPlugin plugin, LimboTask task, long delay, long period) { + LimboSchedulerTask st = new LimboSchedulerTask(plugin, task, taskId, LimboSchedulerTaskType.TIMER_SYNC, period); + if (delay <= 0) { + delay = 1; + } + if (period <= 0) { + period = 1; + } + long tick = Limbo.getInstance().getHeartBeat().getCurrentTick() + delay; + tasksById.put(taskId, st); + List list = registeredTasks.get(tick); + if (list == null) { + list = new ArrayList<>(); + registeredTasks.put(tick, list); + } + list.add(st); + return taskId; + } + + public int runTaskTimer(LimboPlugin plugin, LimboTask task, long delay, long period) { + return runTaskTimer(nextId(), plugin, task, delay, period); + } + + protected int runTaskTimerAsync(int taskId, LimboPlugin plugin, LimboTask task, long delay, long period) { + LimboSchedulerTask st = new LimboSchedulerTask(plugin, task, taskId, LimboSchedulerTaskType.TIMER_ASYNC, period); + if (delay <= 0) { + delay = 1; + } + if (period <= 0) { + period = 1; + } + long tick = Limbo.getInstance().getHeartBeat().getCurrentTick() + delay; + tasksById.put(taskId, st); + List list = registeredTasks.get(tick); + if (list == null) { + list = new ArrayList<>(); + registeredTasks.put(tick, list); + } + list.add(st); + return taskId; + } + + public int runTaskTimerAsync(LimboPlugin plugin, LimboTask task, long delay, long period) { + return runTaskTimerAsync(nextId(), plugin, task, delay, period); + } + + protected CurrentSchedulerTask collectTasks(long currentTick) { + List tasks = registeredTasks.remove(currentTick); + if (tasks == null) { + return null; + } + + List asyncTasks = new LinkedList<>(); + List syncedTasks = new LinkedList<>(); + + for (LimboSchedulerTask task : tasks) { + int taskId = task.getTaskId(); + if (cancelledTasks.contains(taskId)) { + cancelledTasks.remove(taskId); + continue; + } + + switch (task.getType()) { + case ASYNC: + asyncTasks.add(task); + break; + case SYNC: + syncedTasks.add(task); + break; + case TIMER_ASYNC: + asyncTasks.add(task); + runTaskTimerAsync(task.getTaskId(), task.getPlugin(), task.getTask(), task.getPeriod(), task.getPeriod()); + break; + case TIMER_SYNC: + syncedTasks.add(task); + runTaskTimer(task.getTaskId(), task.getPlugin(), task.getTask(), task.getPeriod(), task.getPeriod()); + break; + } + } + + return new CurrentSchedulerTask(syncedTasks, asyncTasks); + } + + public enum LimboSchedulerTaskType { + + SYNC, + ASYNC, + TIMER_SYNC, + TIMER_ASYNC + + } + + public static class CurrentSchedulerTask { + + private final List asyncTasks; + private final List syncedTasks; + + public CurrentSchedulerTask(List syncedTasks, List asyncTasks) { + this.asyncTasks = asyncTasks; + this.syncedTasks = syncedTasks; + } + + public List getAsyncTasks() { + return asyncTasks; + } + + public List getSyncedTasks() { + return syncedTasks; + } + + } + + public static class LimboSchedulerTask { + + private final int taskId; + private final LimboPlugin plugin; + private final LimboTask task; + private final LimboSchedulerTaskType type; + private final long period; + + private LimboSchedulerTask(LimboPlugin plugin, LimboTask task, int taskId, LimboSchedulerTaskType type, long period) { + this.plugin = plugin; + this.task = task; + this.taskId = taskId; + this.type = type; + this.period = period; + } + + public LimboPlugin getPlugin() { + return plugin; + } + + public LimboTask getTask() { + return task; + } + + public int getTaskId() { + return taskId; + } + + public LimboSchedulerTaskType getType() { + return type; + } + + public long getPeriod() { + return period; + } + + } } diff --git a/src/main/java/com/loohp/limbo/scheduler/Tick.java b/src/main/java/com/loohp/limbo/scheduler/Tick.java index 92bbc74..2106cf2 100644 --- a/src/main/java/com/loohp/limbo/scheduler/Tick.java +++ b/src/main/java/com/loohp/limbo/scheduler/Tick.java @@ -1,5 +1,9 @@ package com.loohp.limbo.scheduler; +import com.loohp.limbo.Limbo; +import com.loohp.limbo.scheduler.LimboScheduler.CurrentSchedulerTask; +import com.loohp.limbo.scheduler.LimboScheduler.LimboSchedulerTask; + import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -8,62 +12,58 @@ import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; -import com.loohp.limbo.Limbo; -import com.loohp.limbo.scheduler.LimboScheduler.CurrentSchedulerTask; -import com.loohp.limbo.scheduler.LimboScheduler.LimboSchedulerTask; - public class Tick { - - private int tickingInterval; - private AtomicLong tick = new AtomicLong(0); - - private List threads = new ArrayList<>(); - private Queue asyncTasksQueue = new ConcurrentLinkedQueue<>(); - - public Tick(Limbo instance) { - new Thread(new Runnable() { - @Override - public void run() { - tickingInterval = (int) Math.round(1000.0 / Limbo.getInstance().getServerProperties().getDefinedTicksPerSecond()); - - for (int i = 0; i < 4; i++) { - Thread thread = new Thread(new Runnable() { - @Override - public void run() { - while (instance.isRunning()) { - LimboSchedulerTask task = asyncTasksQueue.poll(); - if (task == null) { - try { - TimeUnit.NANOSECONDS.sleep(10000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } else { - LimboTask limboTask = task.getTask(); - try { - limboTask.run(); - } catch (Throwable e) { - System.err.println("Task " + task.getTaskId() + " threw an exception: " + e.getLocalizedMessage()); - e.printStackTrace(); - } - } - } - } - }); - thread.start(); - threads.add(thread); - } - - while (instance.isRunning()) { - long start = System.currentTimeMillis(); - tick.incrementAndGet(); - instance.getPlayers().forEach(each -> { - if (each.clientConnection.isReady()) { - try { - each.playerInteractManager.update(); - } catch (IOException e) { - e.printStackTrace(); - } + + private int tickingInterval; + private final AtomicLong tick = new AtomicLong(0); + + private final List threads = new ArrayList<>(); + private final Queue asyncTasksQueue = new ConcurrentLinkedQueue<>(); + + public Tick(Limbo instance) { + new Thread(new Runnable() { + @Override + public void run() { + tickingInterval = (int) Math.round(1000.0 / Limbo.getInstance().getServerProperties().getDefinedTicksPerSecond()); + + for (int i = 0; i < 4; i++) { + Thread thread = new Thread(new Runnable() { + @Override + public void run() { + while (instance.isRunning()) { + LimboSchedulerTask task = asyncTasksQueue.poll(); + if (task == null) { + try { + TimeUnit.NANOSECONDS.sleep(10000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } else { + LimboTask limboTask = task.getTask(); + try { + limboTask.run(); + } catch (Throwable e) { + System.err.println("Task " + task.getTaskId() + " threw an exception: " + e.getLocalizedMessage()); + e.printStackTrace(); + } + } + } + } + }); + thread.start(); + threads.add(thread); + } + + while (instance.isRunning()) { + long start = System.currentTimeMillis(); + tick.incrementAndGet(); + instance.getPlayers().forEach(each -> { + if (each.clientConnection.isReady()) { + try { + each.playerInteractManager.update(); + } catch (IOException e) { + e.printStackTrace(); + } /* try { each.getDataWatcher().update(); @@ -71,59 +71,59 @@ public class Tick { e.printStackTrace(); } */ - } - }); - instance.getWorlds().forEach(each -> { - try { - each.update(); - } catch (IllegalArgumentException | IllegalAccessException e) { - e.printStackTrace(); - } - }); - - CurrentSchedulerTask tasks = instance.getScheduler().collectTasks(getCurrentTick()); - if (tasks != null) { - asyncTasksQueue.addAll(tasks.getAsyncTasks()); - - tasks.getSyncedTasks().forEach(task -> { - LimboTask limboTask = task.getTask(); - try { - limboTask.run(); - } catch (Throwable e) { - System.err.println("Task " + task.getTaskId() + " threw an exception: " + e.getLocalizedMessage()); - e.printStackTrace(); - } - }); - } - - long end = System.currentTimeMillis(); - try { - TimeUnit.MILLISECONDS.sleep(tickingInterval - (end - start)); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } - }).start(); - } - - public long getCurrentTick() { - return tick.get(); - } - - @SuppressWarnings("deprecation") - public void waitAndKillThreads(long waitTime) { - long end = System.currentTimeMillis() + waitTime; - for (Thread thread : threads) { - try { - thread.join(Math.max(end - System.currentTimeMillis(), 1)); - } catch (InterruptedException e) { - e.printStackTrace(); - } - if (thread.isAlive()) { - thread.stop(); - } - } - } - + } + }); + instance.getWorlds().forEach(each -> { + try { + each.update(); + } catch (IllegalArgumentException | IllegalAccessException e) { + e.printStackTrace(); + } + }); + + CurrentSchedulerTask tasks = instance.getScheduler().collectTasks(getCurrentTick()); + if (tasks != null) { + asyncTasksQueue.addAll(tasks.getAsyncTasks()); + + tasks.getSyncedTasks().forEach(task -> { + LimboTask limboTask = task.getTask(); + try { + limboTask.run(); + } catch (Throwable e) { + System.err.println("Task " + task.getTaskId() + " threw an exception: " + e.getLocalizedMessage()); + e.printStackTrace(); + } + }); + } + + long end = System.currentTimeMillis(); + try { + TimeUnit.MILLISECONDS.sleep(tickingInterval - (end - start)); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + }).start(); + } + + public long getCurrentTick() { + return tick.get(); + } + + @SuppressWarnings("deprecation") + public void waitAndKillThreads(long waitTime) { + long end = System.currentTimeMillis() + waitTime; + for (Thread thread : threads) { + try { + thread.join(Math.max(end - System.currentTimeMillis(), 1)); + } catch (InterruptedException e) { + e.printStackTrace(); + } + if (thread.isAlive()) { + thread.stop(); + } + } + } + } diff --git a/src/main/java/com/loohp/limbo/server/ClientConnection.java b/src/main/java/com/loohp/limbo/server/ClientConnection.java index b74598b..a675311 100644 --- a/src/main/java/com/loohp/limbo/server/ClientConnection.java +++ b/src/main/java/com/loohp/limbo/server/ClientConnection.java @@ -1,105 +1,50 @@ package com.loohp.limbo.server; +import com.loohp.limbo.Limbo; +import com.loohp.limbo.events.player.*; +import com.loohp.limbo.events.status.StatusPingEvent; +import com.loohp.limbo.file.ServerProperties; +import com.loohp.limbo.location.Location; +import com.loohp.limbo.player.Player; +import com.loohp.limbo.player.PlayerInteractManager; +import com.loohp.limbo.server.packets.*; +import com.loohp.limbo.server.packets.PacketPlayOutPlayerAbilities.PlayerAbilityFlags; +import com.loohp.limbo.server.packets.PacketPlayOutPlayerInfo.PlayerInfoAction; +import com.loohp.limbo.server.packets.PacketPlayOutPlayerInfo.PlayerInfoData; +import com.loohp.limbo.server.packets.PacketPlayOutPlayerInfo.PlayerInfoData.PlayerInfoDataAddPlayer.PlayerSkinProperty; +import com.loohp.limbo.server.packets.PacketPlayOutTabComplete.TabCompleteMatches; +import com.loohp.limbo.utils.*; +import com.loohp.limbo.utils.MojangAPIUtils.SkinResponse; +import com.loohp.limbo.world.BlockPosition; +import com.loohp.limbo.world.World; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.chat.ComponentSerializer; + import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.InetAddress; import java.net.Socket; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; +import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; -import com.loohp.limbo.Limbo; -import com.loohp.limbo.events.player.PlayerJoinEvent; -import com.loohp.limbo.events.player.PlayerLoginEvent; -import com.loohp.limbo.events.player.PlayerMoveEvent; -import com.loohp.limbo.events.player.PlayerQuitEvent; -import com.loohp.limbo.events.player.PlayerSelectedSlotChangeEvent; -import com.loohp.limbo.events.status.StatusPingEvent; -import com.loohp.limbo.server.packets.Packet; -import com.loohp.limbo.server.packets.PacketHandshakingIn; -import com.loohp.limbo.server.packets.PacketLoginInLoginStart; -import com.loohp.limbo.server.packets.PacketLoginOutDisconnect; -import com.loohp.limbo.server.packets.PacketLoginOutLoginSuccess; -import com.loohp.limbo.server.packets.PacketOut; -import com.loohp.limbo.server.packets.PacketPlayInChat; -import com.loohp.limbo.server.packets.PacketPlayInHeldItemChange; -import com.loohp.limbo.server.packets.PacketPlayInKeepAlive; -import com.loohp.limbo.server.packets.PacketPlayInPosition; -import com.loohp.limbo.server.packets.PacketPlayInPositionAndLook; -import com.loohp.limbo.server.packets.PacketPlayInRotation; -import com.loohp.limbo.server.packets.PacketPlayInTabComplete; -import com.loohp.limbo.server.packets.PacketPlayOutDeclareCommands; -import com.loohp.limbo.server.packets.PacketPlayOutDisconnect; -import com.loohp.limbo.server.packets.PacketPlayOutEntityMetadata; -import com.loohp.limbo.server.packets.PacketPlayOutHeldItemChange; -import com.loohp.limbo.server.packets.PacketPlayOutLogin; -import com.loohp.limbo.server.packets.PacketPlayOutPlayerAbilities; -import com.loohp.limbo.server.packets.PacketPlayOutPlayerInfo; -import com.loohp.limbo.server.packets.PacketPlayOutPositionAndLook; -import com.loohp.limbo.server.packets.PacketPlayOutSpawnPosition; -import com.loohp.limbo.server.packets.PacketPlayOutTabComplete; -import com.loohp.limbo.server.packets.PacketPlayOutUpdateViewPosition; -import com.loohp.limbo.server.packets.PacketStatusInPing; -import com.loohp.limbo.server.packets.PacketStatusInRequest; -import com.loohp.limbo.server.packets.PacketStatusOutPong; -import com.loohp.limbo.server.packets.PacketStatusOutResponse; -import com.loohp.limbo.server.packets.PacketPlayOutPlayerAbilities.PlayerAbilityFlags; -import com.loohp.limbo.server.packets.PacketPlayOutPlayerInfo.PlayerInfoAction; -import com.loohp.limbo.server.packets.PacketPlayOutPlayerInfo.PlayerInfoData; -import com.loohp.limbo.server.packets.PacketPlayOutPlayerInfo.PlayerInfoData.PlayerInfoDataAddPlayer.PlayerSkinProperty; -import com.loohp.limbo.server.packets.PacketPlayOutTabComplete.TabCompleteMatches; -import com.loohp.limbo.file.ServerProperties; -import com.loohp.limbo.location.Location; -import com.loohp.limbo.player.Player; -import com.loohp.limbo.player.PlayerInteractManager; -import com.loohp.limbo.utils.CustomStringUtils; -import com.loohp.limbo.utils.DataTypeIO; -import com.loohp.limbo.utils.DeclareCommands; -import com.loohp.limbo.utils.GameMode; -import com.loohp.limbo.utils.MojangAPIUtils; -import com.loohp.limbo.utils.NamespacedKey; -import com.loohp.limbo.utils.MojangAPIUtils.SkinResponse; -import com.loohp.limbo.world.BlockPosition; -import com.loohp.limbo.world.World; - -import net.md_5.bungee.api.ChatColor; -import net.md_5.bungee.api.chat.BaseComponent; -import net.md_5.bungee.api.chat.TextComponent; -import net.md_5.bungee.chat.ComponentSerializer; - public class ClientConnection extends Thread { - - public static enum ClientState { - LEGACY, - HANDSHAKE, - STATUS, - LOGIN, - PLAY, - DISCONNECTED; - } private final Socket client_socket; private boolean running; private ClientState state; - - private Player player; - private AtomicLong lastKeepAlivePayLoad; - - private DataOutputStream output; - private DataInputStream input; - - private InetAddress inetAddress; - - private boolean ready; - + private Player player; + private final AtomicLong lastKeepAlivePayLoad; + private DataOutputStream output; + private DataInputStream input; + private InetAddress inetAddress; + private boolean ready; + public ClientConnection(Socket client_socket) { this.client_socket = client_socket; this.inetAddress = client_socket.getInetAddress(); @@ -107,366 +52,382 @@ public class ClientConnection extends Thread { this.running = false; this.ready = false; } - - public InetAddress getInetAddress() { - return inetAddress; - } - public long getLastKeepAlivePayLoad() { - return lastKeepAlivePayLoad.get(); - } - - public void setLastKeepAlivePayLoad(long payLoad) { - this.lastKeepAlivePayLoad.set(payLoad); - } + public InetAddress getInetAddress() { + return inetAddress; + } + + public long getLastKeepAlivePayLoad() { + return lastKeepAlivePayLoad.get(); + } + + public void setLastKeepAlivePayLoad(long payLoad) { + this.lastKeepAlivePayLoad.set(payLoad); + } + + public Player getPlayer() { + return player; + } - public Player getPlayer() { - return player; - } - public ClientState getClientState() { - return state; + return state; } - - public Socket getSocket() { - return client_socket; - } - - public boolean isRunning() { - return running; - } - - public boolean isReady() { - return ready; - } - - public synchronized void sendPacket(PacketOut packet) throws IOException { - byte[] packetByte = packet.serializePacket(); - DataTypeIO.writeVarInt(output, packetByte.length); - output.write(packetByte); - output.flush(); - } - - public void disconnect(BaseComponent[] reason) { - try { - PacketPlayOutDisconnect packet = new PacketPlayOutDisconnect(ComponentSerializer.toString(reason)); - sendPacket(packet); - } catch (IOException e) {} - try { - client_socket.close(); - } catch (IOException e) {} - } - - private void disconnectDuringLogin(BaseComponent[] reason) { - try { - PacketLoginOutDisconnect packet = new PacketLoginOutDisconnect(ComponentSerializer.toString(reason)); - sendPacket(packet); - } catch (IOException e) {} - try { - client_socket.close(); - } catch (IOException e) {} - } - @SuppressWarnings("deprecation") - @Override + public Socket getSocket() { + return client_socket; + } + + public boolean isRunning() { + return running; + } + + public boolean isReady() { + return ready; + } + + public synchronized void sendPacket(PacketOut packet) throws IOException { + byte[] packetByte = packet.serializePacket(); + DataTypeIO.writeVarInt(output, packetByte.length); + output.write(packetByte); + output.flush(); + } + + public void disconnect(BaseComponent[] reason) { + try { + PacketPlayOutDisconnect packet = new PacketPlayOutDisconnect(ComponentSerializer.toString(reason)); + sendPacket(packet); + } catch (IOException e) { + } + try { + client_socket.close(); + } catch (IOException e) { + } + } + + private void disconnectDuringLogin(BaseComponent[] reason) { + try { + PacketLoginOutDisconnect packet = new PacketLoginOutDisconnect(ComponentSerializer.toString(reason)); + sendPacket(packet); + } catch (IOException e) { + } + try { + client_socket.close(); + } catch (IOException e) { + } + } + + @SuppressWarnings("deprecation") + @Override public void run() { running = true; state = ClientState.HANDSHAKE; - try { - client_socket.setKeepAlive(true); - input = new DataInputStream(client_socket.getInputStream()); - output = new DataOutputStream(client_socket.getOutputStream()); - int handShakeSize = DataTypeIO.readVarInt(input); + try { + client_socket.setKeepAlive(true); + input = new DataInputStream(client_socket.getInputStream()); + output = new DataOutputStream(client_socket.getOutputStream()); + int handShakeSize = DataTypeIO.readVarInt(input); - //legacy ping - if (handShakeSize == 0xFE) { - state = ClientState.LEGACY; - output.writeByte(255); - String str = inetAddress.getHostName() + ":" + client_socket.getPort(); - Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Legacy Status has pinged"); - ServerProperties p = Limbo.getInstance().getServerProperties(); - StatusPingEvent event = Limbo.getInstance().getEventsManager().callEvent(new StatusPingEvent(this, p.getVersionString(), p.getProtocol(), ComponentSerializer.parse(p.getMotdJson()), p.getMaxPlayers(), Limbo.getInstance().getPlayers().size(), p.getFavicon().orElse(null))); - String response = Limbo.getInstance().buildLegacyPingResponse(event.getVersion(), event.getMotd(), event.getMaxPlayers(), event.getPlayersOnline()); - byte[] bytes = response.getBytes(StandardCharsets.UTF_16BE); - output.writeShort(response.length()); - output.write(bytes); - - client_socket.close(); - state = ClientState.DISCONNECTED; - } - - @SuppressWarnings("unused") - int handShakeId = DataTypeIO.readVarInt(input); - - PacketHandshakingIn handshake = new PacketHandshakingIn(input); - - boolean isBungeecord = Limbo.getInstance().getServerProperties().isBungeecord(); - String bungeeForwarding = handshake.getServerAddress(); - UUID bungeeUUID = null; - SkinResponse bungeeSkin = null; - - try { - switch (handshake.getHandshakeType()) { - case STATUS: - state = ClientState.STATUS; - while (client_socket.isConnected()) { - DataTypeIO.readVarInt(input); - int packetId = DataTypeIO.readVarInt(input); - Class packetType = Packet.getStatusIn().get(packetId); - if (packetType == null) { - //do nothing - } else if (packetType.equals(PacketStatusInRequest.class)) { - String str = inetAddress.getHostName() + ":" + client_socket.getPort(); - if (Limbo.getInstance().getServerProperties().handshakeVerboseEnabled()) { - Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Handshake Status has pinged"); - } - ServerProperties p = Limbo.getInstance().getServerProperties(); - StatusPingEvent event = Limbo.getInstance().getEventsManager().callEvent(new StatusPingEvent(this, p.getVersionString(), p.getProtocol(), ComponentSerializer.parse(p.getMotdJson()), p.getMaxPlayers(), Limbo.getInstance().getPlayers().size(), p.getFavicon().orElse(null))); - PacketStatusOutResponse packet = new PacketStatusOutResponse(Limbo.getInstance().buildServerListResponseJson(event.getVersion(), event.getProtocol(), event.getMotd(), event.getMaxPlayers(), event.getPlayersOnline(), event.getFavicon())); - sendPacket(packet); - } else if (packetType.equals(PacketStatusInPing.class)) { - PacketStatusInPing ping = new PacketStatusInPing(input); - PacketStatusOutPong packet = new PacketStatusOutPong(ping.getPayload()); - sendPacket(packet); - break; - } - } - break; - case LOGIN: - state = ClientState.LOGIN; - - if (isBungeecord) { - try { - String[] data = bungeeForwarding.split("\\x00"); - //String host = data[0]; - String ip = data[1]; - - bungeeUUID = UUID.fromString(data[2].replaceFirst("([0-9a-fA-F]{8})([0-9a-fA-F]{4})([0-9a-fA-F]{4})([0-9a-fA-F]{4})([0-9a-fA-F]+)", "$1-$2-$3-$4-$5")); - inetAddress = InetAddress.getByName(ip); - - if (data.length > 3) { - String skinJson = data[3]; - - String skin = skinJson.split("\"value\":\"")[1].split("\"")[0]; - String signature = skinJson.split("\"signature\":\"")[1].split("\"")[0]; - bungeeSkin = new SkinResponse(skin, signature); - } - } catch (Exception e) { - Limbo.getInstance().getConsole().sendMessage("If you wish to use bungeecord's IP forwarding, please enable that in your bungeecord config.yml as well!"); - disconnectDuringLogin(new BaseComponent[] {new TextComponent(ChatColor.RED + "Please connect from the proxy!")}); - } - } - - while (client_socket.isConnected()) { - int size = DataTypeIO.readVarInt(input); - int packetId = DataTypeIO.readVarInt(input); - Class packetType = Packet.getLoginIn().get(packetId); - - if (packetType == null) { - input.skipBytes(size - DataTypeIO.getVarIntLength(packetId)); - } else if (packetType.equals(PacketLoginInLoginStart.class)) { - PacketLoginInLoginStart start = new PacketLoginInLoginStart(input); - String username = start.getUsername(); - UUID uuid = isBungeecord ? bungeeUUID : UUID.nameUUIDFromBytes(("OfflinePlayer:" + username).getBytes(StandardCharsets.UTF_8)); - - PacketLoginOutLoginSuccess success = new PacketLoginOutLoginSuccess(uuid, username); - sendPacket(success); - - state = ClientState.PLAY; - - player = new Player(this, username, uuid, Limbo.getInstance().getNextEntityId(), Limbo.getInstance().getServerProperties().getWorldSpawn(), new PlayerInteractManager()); - player.setSkinLayers((byte) (0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40)); - Limbo.getInstance().addPlayer(player); - - break; - } else { - input.skipBytes(size - DataTypeIO.getVarIntLength(packetId)); - } - } - - PlayerLoginEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerLoginEvent(this, false)); - if (event.isCancelled()) { - disconnectDuringLogin(event.getCancelReason()); - } - - break; - } - } catch (Exception e) { - client_socket.close(); - state = ClientState.DISCONNECTED; - } - - if (state == ClientState.PLAY) { - - TimeUnit.MILLISECONDS.sleep(500); + //legacy ping + if (handShakeSize == 0xFE) { + state = ClientState.LEGACY; + output.writeByte(255); + String str = inetAddress.getHostName() + ":" + client_socket.getPort(); + Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Legacy Status has pinged"); + ServerProperties p = Limbo.getInstance().getServerProperties(); + StatusPingEvent event = Limbo.getInstance().getEventsManager().callEvent(new StatusPingEvent(this, p.getVersionString(), p.getProtocol(), ComponentSerializer.parse(p.getMotdJson()), p.getMaxPlayers(), Limbo.getInstance().getPlayers().size(), p.getFavicon().orElse(null))); + String response = Limbo.getInstance().buildLegacyPingResponse(event.getVersion(), event.getMotd(), event.getMaxPlayers(), event.getPlayersOnline()); + byte[] bytes = response.getBytes(StandardCharsets.UTF_16BE); + output.writeShort(response.length()); + output.write(bytes); - ServerProperties properties = Limbo.getInstance().getServerProperties(); - Location worldSpawn = properties.getWorldSpawn(); - - PlayerJoinEvent joinEvent = Limbo.getInstance().getEventsManager().callEvent(new PlayerJoinEvent(player, worldSpawn)); - worldSpawn = joinEvent.getSpawnLocation(); - World world = worldSpawn.getWorld(); + client_socket.close(); + state = ClientState.DISCONNECTED; + } - PacketPlayOutLogin join = new PacketPlayOutLogin(player.getEntityId(), false, properties.getDefaultGamemode(), Limbo.getInstance().getWorlds().stream().map(each -> new NamespacedKey(each.getName()).toString()).collect(Collectors.toList()).toArray(new String[Limbo.getInstance().getWorlds().size()]), Limbo.getInstance().getDimensionRegistry().getCodec(), world, 0, (byte) properties.getMaxPlayers(), 8, properties.isReducedDebugInfo(), true, false, true); - sendPacket(join); - Limbo.getInstance().getUnsafe().setPlayerGameModeSilently(player, properties.getDefaultGamemode()); - - player.playerInteractManager.update(); - - SkinResponse skinresponce = isBungeecord && bungeeSkin != null ? bungeeSkin : MojangAPIUtils.getSkinFromMojangServer(player.getName()); - PlayerSkinProperty skin = skinresponce != null ? new PlayerSkinProperty(skinresponce.getSkin(), skinresponce.getSignature()) : null; - PacketPlayOutPlayerInfo info = new PacketPlayOutPlayerInfo(PlayerInfoAction.ADD_PLAYER, player.getUniqueId(), new PlayerInfoData.PlayerInfoDataAddPlayer(player.getName(), Optional.ofNullable(skin), properties.getDefaultGamemode(), 0, false, Optional.empty())); - sendPacket(info); - - Set flags = new HashSet<>(); - if (properties.isAllowFlight()) { - flags.add(PlayerAbilityFlags.FLY); - } - if (player.getGamemode().equals(GameMode.CREATIVE)) { - flags.add(PlayerAbilityFlags.CREATIVE); - } - PacketPlayOutPlayerAbilities abilities = new PacketPlayOutPlayerAbilities(0.05F, 0.1F, flags.toArray(new PlayerAbilityFlags[flags.size()])); - sendPacket(abilities); + @SuppressWarnings("unused") + int handShakeId = DataTypeIO.readVarInt(input); - String str = inetAddress.getHostName() + ":" + client_socket.getPort() + "|" + player.getName(); - Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Player had connected to the Limbo server!"); + PacketHandshakingIn handshake = new PacketHandshakingIn(input); - PacketPlayOutDeclareCommands declare = DeclareCommands.getDeclareCommandsPacket(player); - if (declare != null) { - sendPacket(declare); - } + boolean isBungeecord = Limbo.getInstance().getServerProperties().isBungeecord(); + String bungeeForwarding = handshake.getServerAddress(); + UUID bungeeUUID = null; + SkinResponse bungeeSkin = null; - PacketPlayOutSpawnPosition spawnPos = new PacketPlayOutSpawnPosition(BlockPosition.from(worldSpawn)); - sendPacket(spawnPos); + try { + switch (handshake.getHandshakeType()) { + case STATUS: + state = ClientState.STATUS; + while (client_socket.isConnected()) { + DataTypeIO.readVarInt(input); + int packetId = DataTypeIO.readVarInt(input); + Class packetType = Packet.getStatusIn().get(packetId); + if (packetType == null) { + //do nothing + } else if (packetType.equals(PacketStatusInRequest.class)) { + String str = inetAddress.getHostName() + ":" + client_socket.getPort(); + if (Limbo.getInstance().getServerProperties().handshakeVerboseEnabled()) { + Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Handshake Status has pinged"); + } + ServerProperties p = Limbo.getInstance().getServerProperties(); + StatusPingEvent event = Limbo.getInstance().getEventsManager().callEvent(new StatusPingEvent(this, p.getVersionString(), p.getProtocol(), ComponentSerializer.parse(p.getMotdJson()), p.getMaxPlayers(), Limbo.getInstance().getPlayers().size(), p.getFavicon().orElse(null))); + PacketStatusOutResponse packet = new PacketStatusOutResponse(Limbo.getInstance().buildServerListResponseJson(event.getVersion(), event.getProtocol(), event.getMotd(), event.getMaxPlayers(), event.getPlayersOnline(), event.getFavicon())); + sendPacket(packet); + } else if (packetType.equals(PacketStatusInPing.class)) { + PacketStatusInPing ping = new PacketStatusInPing(input); + PacketStatusOutPong packet = new PacketStatusOutPong(ping.getPayload()); + sendPacket(packet); + break; + } + } + break; + case LOGIN: + state = ClientState.LOGIN; - PacketPlayOutPositionAndLook positionLook = new PacketPlayOutPositionAndLook(worldSpawn.getX(), worldSpawn.getY(), worldSpawn.getZ(), worldSpawn.getYaw(), worldSpawn.getPitch(), 1); - Limbo.getInstance().getUnsafe().setPlayerLocationSilently(player, new Location(world, worldSpawn.getX(), worldSpawn.getY(), worldSpawn.getZ(), worldSpawn.getYaw(), worldSpawn.getPitch())); - sendPacket(positionLook); + if (isBungeecord) { + try { + String[] data = bungeeForwarding.split("\\x00"); + //String host = data[0]; + String ip = data[1]; - player.getDataWatcher().update(); - PacketPlayOutEntityMetadata show = new PacketPlayOutEntityMetadata(player, false, Player.class.getDeclaredField("skinLayers")); - sendPacket(show); + bungeeUUID = UUID.fromString(data[2].replaceFirst("([0-9a-fA-F]{8})([0-9a-fA-F]{4})([0-9a-fA-F]{4})([0-9a-fA-F]{4})([0-9a-fA-F]+)", "$1-$2-$3-$4-$5")); + inetAddress = InetAddress.getByName(ip); - ready = true; + if (data.length > 3) { + String skinJson = data[3]; - while (client_socket.isConnected()) { - try { - int size = DataTypeIO.readVarInt(input); - int packetId = DataTypeIO.readVarInt(input); - Class packetType = Packet.getPlayIn().get(packetId); - //Limbo.getInstance().getConsole().sendMessage(packetId + " -> " + packetType); - CheckedConsumer processMoveEvent = event -> { - Location originalTo = event.getTo().clone(); - if (event.isCancelled()) { - Location returnTo = event.getFrom(); - PacketPlayOutPositionAndLook cancel = new PacketPlayOutPositionAndLook(returnTo.getX(), returnTo.getY(), returnTo.getZ(), returnTo.getYaw(), returnTo.getPitch(), 1); - sendPacket(cancel); - } else { - Location to = event.getTo(); - Limbo.getInstance().getUnsafe().setPlayerLocationSilently(player, to); - // If an event handler used setTo, let's make sure we tell the player about it. - if (!originalTo.equals(to)) { - PacketPlayOutPositionAndLook pos = new PacketPlayOutPositionAndLook(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch(), 1); - sendPacket(pos); - } - PacketPlayOutUpdateViewPosition response = new PacketPlayOutUpdateViewPosition((int) player.getLocation().getX() >> 4, (int) player.getLocation().getZ() >> 4); - sendPacket(response); - } - }; - if (packetType == null) { - input.skipBytes(size - DataTypeIO.getVarIntLength(packetId)); - } else if (packetType.equals(PacketPlayInPositionAndLook.class)) { - PacketPlayInPositionAndLook pos = new PacketPlayInPositionAndLook(input); - Location from = player.getLocation(); - Location to = new Location(player.getWorld(), pos.getX(), pos.getY(), pos.getZ(), pos.getYaw(), pos.getPitch()); + String skin = skinJson.split("\"value\":\"")[1].split("\"")[0]; + String signature = skinJson.split("\"signature\":\"")[1].split("\"")[0]; + bungeeSkin = new SkinResponse(skin, signature); + } + } catch (Exception e) { + Limbo.getInstance().getConsole().sendMessage("If you wish to use bungeecord's IP forwarding, please enable that in your bungeecord config.yml as well!"); + disconnectDuringLogin(new BaseComponent[]{new TextComponent(ChatColor.RED + "Please connect from the proxy!")}); + } + } - PlayerMoveEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerMoveEvent(player, from, to)); - processMoveEvent.consume(event); - } else if (packetType.equals(PacketPlayInPosition.class)) { - PacketPlayInPosition pos = new PacketPlayInPosition(input); - Location from = player.getLocation(); - Location to = new Location(player.getWorld(), pos.getX(), pos.getY(), pos.getZ(), player.getLocation().getYaw(), player.getLocation().getPitch()); + while (client_socket.isConnected()) { + int size = DataTypeIO.readVarInt(input); + int packetId = DataTypeIO.readVarInt(input); + Class packetType = Packet.getLoginIn().get(packetId); - PlayerMoveEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerMoveEvent(player, from, to)); - processMoveEvent.consume(event); - } else if (packetType.equals(PacketPlayInRotation.class)) { - PacketPlayInRotation pos = new PacketPlayInRotation(input); - Location from = player.getLocation(); - Location to = new Location(player.getWorld(), player.getLocation().getX(), player.getLocation().getY(), player.getLocation().getZ(), pos.getYaw(), pos.getPitch()); + if (packetType == null) { + input.skipBytes(size - DataTypeIO.getVarIntLength(packetId)); + } else if (packetType.equals(PacketLoginInLoginStart.class)) { + PacketLoginInLoginStart start = new PacketLoginInLoginStart(input); + String username = start.getUsername(); + UUID uuid = isBungeecord ? bungeeUUID : UUID.nameUUIDFromBytes(("OfflinePlayer:" + username).getBytes(StandardCharsets.UTF_8)); - PlayerMoveEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerMoveEvent(player, from, to)); - processMoveEvent.consume(event); - } else if (packetType.equals(PacketPlayInKeepAlive.class)) { - PacketPlayInKeepAlive alive = new PacketPlayInKeepAlive(input); - if (alive.getPayload() != getLastKeepAlivePayLoad()) { - Limbo.getInstance().getConsole().sendMessage("Incorrect Payload recieved in KeepAlive packet for player " + player.getName()); - break; - } - } else if (packetType.equals(PacketPlayInTabComplete.class)) { - PacketPlayInTabComplete request = new PacketPlayInTabComplete(input); - String[] command = CustomStringUtils.splitStringToArgs(request.getText().substring(1)); + PacketLoginOutLoginSuccess success = new PacketLoginOutLoginSuccess(uuid, username); + sendPacket(success); - List matches = new ArrayList(); - - matches.addAll(Limbo.getInstance().getPluginManager().getTabOptions(player, command).stream().map(each -> new TabCompleteMatches(each)).collect(Collectors.toList())); - - int start = CustomStringUtils.getIndexOfArg(request.getText(), command.length - 1) + 1; - int length = command[command.length - 1].length(); - - PacketPlayOutTabComplete response = new PacketPlayOutTabComplete(request.getId(), start, length, matches.toArray(new TabCompleteMatches[matches.size()])); - sendPacket(response); - } else if (packetType.equals(PacketPlayInChat.class)) { - PacketPlayInChat chat = new PacketPlayInChat(input); - if (chat.getMessage().startsWith("/")) { - Limbo.getInstance().dispatchCommand(player, chat.getMessage()); - } else { - player.chat(chat.getMessage()); - } - } else if (packetType.equals(PacketPlayInHeldItemChange.class)) { - PacketPlayInHeldItemChange change = new PacketPlayInHeldItemChange(input); - PlayerSelectedSlotChangeEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerSelectedSlotChangeEvent(player, (byte) change.getSlot())); - if (event.isCancelled()) { - PacketPlayOutHeldItemChange cancelPacket = new PacketPlayOutHeldItemChange(player.getSelectedSlot()); - sendPacket(cancelPacket); - } else if (change.getSlot() != event.getSlot()) { - PacketPlayOutHeldItemChange changePacket = new PacketPlayOutHeldItemChange(event.getSlot()); - sendPacket(changePacket); - Limbo.getInstance().getUnsafe().setSelectedSlotSilently(player, event.getSlot()); - } else { - Limbo.getInstance().getUnsafe().setSelectedSlotSilently(player, event.getSlot()); - } - } else { - input.skipBytes(size - DataTypeIO.getVarIntLength(packetId)); - } + state = ClientState.PLAY; - } catch (Exception e) { - break; - } - } + player = new Player(this, username, uuid, Limbo.getInstance().getNextEntityId(), Limbo.getInstance().getServerProperties().getWorldSpawn(), new PlayerInteractManager()); + player.setSkinLayers((byte) (0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40)); + Limbo.getInstance().addPlayer(player); - Limbo.getInstance().getEventsManager().callEvent(new PlayerQuitEvent(player)); + break; + } else { + input.skipBytes(size - DataTypeIO.getVarIntLength(packetId)); + } + } - str = inetAddress.getHostName() + ":" + client_socket.getPort() + "|" + player.getName(); - Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Player had disconnected!"); + PlayerLoginEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerLoginEvent(this, false)); + if (event.isCancelled()) { + disconnectDuringLogin(event.getCancelReason()); + } - } + break; + } + } catch (Exception e) { + client_socket.close(); + state = ClientState.DISCONNECTED; + } - } catch (Exception e) {e.printStackTrace();} + if (state == ClientState.PLAY) { - try { - client_socket.close(); - } catch (IOException e) {} - state = ClientState.DISCONNECTED; + TimeUnit.MILLISECONDS.sleep(500); - if (player != null) { - Limbo.getInstance().removePlayer(player); - } - Limbo.getInstance().getServerConnection().getClients().remove(this); - running = false; - } + ServerProperties properties = Limbo.getInstance().getServerProperties(); + Location worldSpawn = properties.getWorldSpawn(); - @FunctionalInterface - public interface CheckedConsumer { - void consume(T t) throws TException; - } + PlayerJoinEvent joinEvent = Limbo.getInstance().getEventsManager().callEvent(new PlayerJoinEvent(player, worldSpawn)); + worldSpawn = joinEvent.getSpawnLocation(); + World world = worldSpawn.getWorld(); + + PacketPlayOutLogin join = new PacketPlayOutLogin(player.getEntityId(), false, properties.getDefaultGamemode(), Limbo.getInstance().getWorlds().stream().map(each -> new NamespacedKey(each.getName()).toString()).collect(Collectors.toList()).toArray(new String[Limbo.getInstance().getWorlds().size()]), Limbo.getInstance().getDimensionRegistry().getCodec(), world, 0, (byte) properties.getMaxPlayers(), 8, properties.isReducedDebugInfo(), true, false, true); + sendPacket(join); + Limbo.getInstance().getUnsafe().setPlayerGameModeSilently(player, properties.getDefaultGamemode()); + + player.playerInteractManager.update(); + + SkinResponse skinresponce = isBungeecord && bungeeSkin != null ? bungeeSkin : MojangAPIUtils.getSkinFromMojangServer(player.getName()); + PlayerSkinProperty skin = skinresponce != null ? new PlayerSkinProperty(skinresponce.getSkin(), skinresponce.getSignature()) : null; + PacketPlayOutPlayerInfo info = new PacketPlayOutPlayerInfo(PlayerInfoAction.ADD_PLAYER, player.getUniqueId(), new PlayerInfoData.PlayerInfoDataAddPlayer(player.getName(), Optional.ofNullable(skin), properties.getDefaultGamemode(), 0, false, Optional.empty())); + sendPacket(info); + + Set flags = new HashSet<>(); + if (properties.isAllowFlight()) { + flags.add(PlayerAbilityFlags.FLY); + } + if (player.getGamemode().equals(GameMode.CREATIVE)) { + flags.add(PlayerAbilityFlags.CREATIVE); + } + PacketPlayOutPlayerAbilities abilities = new PacketPlayOutPlayerAbilities(0.05F, 0.1F, flags.toArray(new PlayerAbilityFlags[flags.size()])); + sendPacket(abilities); + + String str = inetAddress.getHostName() + ":" + client_socket.getPort() + "|" + player.getName(); + Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Player had connected to the Limbo server!"); + + PacketPlayOutDeclareCommands declare = DeclareCommands.getDeclareCommandsPacket(player); + if (declare != null) { + sendPacket(declare); + } + + PacketPlayOutSpawnPosition spawnPos = new PacketPlayOutSpawnPosition(BlockPosition.from(worldSpawn)); + sendPacket(spawnPos); + + PacketPlayOutPositionAndLook positionLook = new PacketPlayOutPositionAndLook(worldSpawn.getX(), worldSpawn.getY(), worldSpawn.getZ(), worldSpawn.getYaw(), worldSpawn.getPitch(), 1); + Limbo.getInstance().getUnsafe().setPlayerLocationSilently(player, new Location(world, worldSpawn.getX(), worldSpawn.getY(), worldSpawn.getZ(), worldSpawn.getYaw(), worldSpawn.getPitch())); + sendPacket(positionLook); + + player.getDataWatcher().update(); + PacketPlayOutEntityMetadata show = new PacketPlayOutEntityMetadata(player, false, Player.class.getDeclaredField("skinLayers")); + sendPacket(show); + + ready = true; + + while (client_socket.isConnected()) { + try { + int size = DataTypeIO.readVarInt(input); + int packetId = DataTypeIO.readVarInt(input); + Class packetType = Packet.getPlayIn().get(packetId); + //Limbo.getInstance().getConsole().sendMessage(packetId + " -> " + packetType); + CheckedConsumer processMoveEvent = event -> { + Location originalTo = event.getTo().clone(); + if (event.isCancelled()) { + Location returnTo = event.getFrom(); + PacketPlayOutPositionAndLook cancel = new PacketPlayOutPositionAndLook(returnTo.getX(), returnTo.getY(), returnTo.getZ(), returnTo.getYaw(), returnTo.getPitch(), 1); + sendPacket(cancel); + } else { + Location to = event.getTo(); + Limbo.getInstance().getUnsafe().setPlayerLocationSilently(player, to); + // If an event handler used setTo, let's make sure we tell the player about it. + if (!originalTo.equals(to)) { + PacketPlayOutPositionAndLook pos = new PacketPlayOutPositionAndLook(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch(), 1); + sendPacket(pos); + } + PacketPlayOutUpdateViewPosition response = new PacketPlayOutUpdateViewPosition((int) player.getLocation().getX() >> 4, (int) player.getLocation().getZ() >> 4); + sendPacket(response); + } + }; + if (packetType == null) { + input.skipBytes(size - DataTypeIO.getVarIntLength(packetId)); + } else if (packetType.equals(PacketPlayInPositionAndLook.class)) { + PacketPlayInPositionAndLook pos = new PacketPlayInPositionAndLook(input); + Location from = player.getLocation(); + Location to = new Location(player.getWorld(), pos.getX(), pos.getY(), pos.getZ(), pos.getYaw(), pos.getPitch()); + + PlayerMoveEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerMoveEvent(player, from, to)); + processMoveEvent.consume(event); + } else if (packetType.equals(PacketPlayInPosition.class)) { + PacketPlayInPosition pos = new PacketPlayInPosition(input); + Location from = player.getLocation(); + Location to = new Location(player.getWorld(), pos.getX(), pos.getY(), pos.getZ(), player.getLocation().getYaw(), player.getLocation().getPitch()); + + PlayerMoveEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerMoveEvent(player, from, to)); + processMoveEvent.consume(event); + } else if (packetType.equals(PacketPlayInRotation.class)) { + PacketPlayInRotation pos = new PacketPlayInRotation(input); + Location from = player.getLocation(); + Location to = new Location(player.getWorld(), player.getLocation().getX(), player.getLocation().getY(), player.getLocation().getZ(), pos.getYaw(), pos.getPitch()); + + PlayerMoveEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerMoveEvent(player, from, to)); + processMoveEvent.consume(event); + } else if (packetType.equals(PacketPlayInKeepAlive.class)) { + PacketPlayInKeepAlive alive = new PacketPlayInKeepAlive(input); + if (alive.getPayload() != getLastKeepAlivePayLoad()) { + Limbo.getInstance().getConsole().sendMessage("Incorrect Payload recieved in KeepAlive packet for player " + player.getName()); + break; + } + } else if (packetType.equals(PacketPlayInTabComplete.class)) { + PacketPlayInTabComplete request = new PacketPlayInTabComplete(input); + String[] command = CustomStringUtils.splitStringToArgs(request.getText().substring(1)); + + List matches = new ArrayList(); + + matches.addAll(Limbo.getInstance().getPluginManager().getTabOptions(player, command).stream().map(each -> new TabCompleteMatches(each)).collect(Collectors.toList())); + + int start = CustomStringUtils.getIndexOfArg(request.getText(), command.length - 1) + 1; + int length = command[command.length - 1].length(); + + PacketPlayOutTabComplete response = new PacketPlayOutTabComplete(request.getId(), start, length, matches.toArray(new TabCompleteMatches[matches.size()])); + sendPacket(response); + } else if (packetType.equals(PacketPlayInChat.class)) { + PacketPlayInChat chat = new PacketPlayInChat(input); + if (chat.getMessage().startsWith("/")) { + Limbo.getInstance().dispatchCommand(player, chat.getMessage()); + } else { + player.chat(chat.getMessage()); + } + } else if (packetType.equals(PacketPlayInHeldItemChange.class)) { + PacketPlayInHeldItemChange change = new PacketPlayInHeldItemChange(input); + PlayerSelectedSlotChangeEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerSelectedSlotChangeEvent(player, (byte) change.getSlot())); + if (event.isCancelled()) { + PacketPlayOutHeldItemChange cancelPacket = new PacketPlayOutHeldItemChange(player.getSelectedSlot()); + sendPacket(cancelPacket); + } else if (change.getSlot() != event.getSlot()) { + PacketPlayOutHeldItemChange changePacket = new PacketPlayOutHeldItemChange(event.getSlot()); + sendPacket(changePacket); + Limbo.getInstance().getUnsafe().setSelectedSlotSilently(player, event.getSlot()); + } else { + Limbo.getInstance().getUnsafe().setSelectedSlotSilently(player, event.getSlot()); + } + } else { + input.skipBytes(size - DataTypeIO.getVarIntLength(packetId)); + } + + } catch (Exception e) { + break; + } + } + + Limbo.getInstance().getEventsManager().callEvent(new PlayerQuitEvent(player)); + + str = inetAddress.getHostName() + ":" + client_socket.getPort() + "|" + player.getName(); + Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Player had disconnected!"); + + } + + } catch (Exception e) { + e.printStackTrace(); + } + + try { + client_socket.close(); + } catch (IOException e) { + } + state = ClientState.DISCONNECTED; + + if (player != null) { + Limbo.getInstance().removePlayer(player); + } + Limbo.getInstance().getServerConnection().getClients().remove(this); + running = false; + } + + public enum ClientState { + LEGACY, + HANDSHAKE, + STATUS, + LOGIN, + PLAY, + DISCONNECTED + } + + @FunctionalInterface + public interface CheckedConsumer { + void consume(T t) throws TException; + } } diff --git a/src/main/java/com/loohp/limbo/server/KeepAliveSender.java b/src/main/java/com/loohp/limbo/server/KeepAliveSender.java index b7eae26..e2de331 100644 --- a/src/main/java/com/loohp/limbo/server/KeepAliveSender.java +++ b/src/main/java/com/loohp/limbo/server/KeepAliveSender.java @@ -1,40 +1,41 @@ package com.loohp.limbo.server; -import java.io.IOException; -import java.util.Random; -import java.util.concurrent.TimeUnit; - import com.loohp.limbo.Limbo; import com.loohp.limbo.server.ClientConnection.ClientState; import com.loohp.limbo.server.packets.PacketPlayOutKeepAlive; +import java.io.IOException; +import java.util.Random; +import java.util.concurrent.TimeUnit; + public class KeepAliveSender extends Thread { - - private Random random; - - public KeepAliveSender() { - random = new Random(); - start(); - } - - @Override - public void run() { - while (true) { - try { - for (ClientConnection client : Limbo.getInstance().getServerConnection().getClients()) { - if (client.getClientState() != null && client.getClientState().equals(ClientState.PLAY)) { - try { - PacketPlayOutKeepAlive packet = new PacketPlayOutKeepAlive(random.nextLong()); - client.setLastKeepAlivePayLoad(packet.getPayload()); - client.sendPacket(packet); - } catch (IOException ignore) {} - } - } - TimeUnit.SECONDS.sleep(5); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } + + private final Random random; + + public KeepAliveSender() { + random = new Random(); + start(); + } + + @Override + public void run() { + while (true) { + try { + for (ClientConnection client : Limbo.getInstance().getServerConnection().getClients()) { + if (client.getClientState() != null && client.getClientState().equals(ClientState.PLAY)) { + try { + PacketPlayOutKeepAlive packet = new PacketPlayOutKeepAlive(random.nextLong()); + client.setLastKeepAlivePayLoad(packet.getPayload()); + client.sendPacket(packet); + } catch (IOException ignore) { + } + } + } + TimeUnit.SECONDS.sleep(5); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } } diff --git a/src/main/java/com/loohp/limbo/server/ServerConnection.java b/src/main/java/com/loohp/limbo/server/ServerConnection.java index e8298bf..23eb3b5 100644 --- a/src/main/java/com/loohp/limbo/server/ServerConnection.java +++ b/src/main/java/com/loohp/limbo/server/ServerConnection.java @@ -1,5 +1,7 @@ package com.loohp.limbo.server; +import com.loohp.limbo.Limbo; + import java.io.IOException; import java.net.InetAddress; import java.net.ServerSocket; @@ -7,52 +9,50 @@ import java.net.Socket; import java.util.ArrayList; import java.util.List; -import com.loohp.limbo.Limbo; - public class ServerConnection extends Thread { - - private ServerSocket serverSocket; - private List clients; - private String ip; - private int port; - private KeepAliveSender keepAliveSender; - public ServerConnection(String ip, int port) { - clients = new ArrayList(); - this.ip = ip; - this.port = port; - start(); - keepAliveSender = new KeepAliveSender(); - } - - @Override - public void run() { - try { - serverSocket = new ServerSocket(port, 50, InetAddress.getByName(ip)); - Limbo.getInstance().getConsole().sendMessage("Limbo server listening on /" + serverSocket.getInetAddress().getHostName() + ":" + serverSocket.getLocalPort()); - while (true) { - Socket connection = serverSocket.accept(); - //String str = connection.getInetAddress().getHostName() + ":" + connection.getPort(); - //Limbo.getInstance().getConsole().sendMessage("[/127.0.0.1:57310] <-> InitialHandler has pinged); - ClientConnection sc = new ClientConnection(connection); - clients.add(sc); - sc.start(); - } - } catch(IOException e) { - e.printStackTrace(); - } - } - - public KeepAliveSender getKeepAliveSender() { - return keepAliveSender; - } + private ServerSocket serverSocket; + private final List clients; + private final String ip; + private final int port; + private final KeepAliveSender keepAliveSender; - public ServerSocket getServerSocket() { - return serverSocket; - } + public ServerConnection(String ip, int port) { + clients = new ArrayList(); + this.ip = ip; + this.port = port; + start(); + keepAliveSender = new KeepAliveSender(); + } - public List getClients() { - return clients; - } + @Override + public void run() { + try { + serverSocket = new ServerSocket(port, 50, InetAddress.getByName(ip)); + Limbo.getInstance().getConsole().sendMessage("Limbo server listening on /" + serverSocket.getInetAddress().getHostName() + ":" + serverSocket.getLocalPort()); + while (true) { + Socket connection = serverSocket.accept(); + //String str = connection.getInetAddress().getHostName() + ":" + connection.getPort(); + //Limbo.getInstance().getConsole().sendMessage("[/127.0.0.1:57310] <-> InitialHandler has pinged); + ClientConnection sc = new ClientConnection(connection); + clients.add(sc); + sc.start(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + public KeepAliveSender getKeepAliveSender() { + return keepAliveSender; + } + + public ServerSocket getServerSocket() { + return serverSocket; + } + + public List getClients() { + return clients; + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/Packet.java b/src/main/java/com/loohp/limbo/server/packets/Packet.java index cccf4fb..c9589df 100644 --- a/src/main/java/com/loohp/limbo/server/packets/Packet.java +++ b/src/main/java/com/loohp/limbo/server/packets/Packet.java @@ -4,71 +4,71 @@ import java.util.Map; public class Packet { - private static Map> HandshakeIn; + private static Map> HandshakeIn; - private static Map> StatusIn; - private static Map, Integer> StatusOut; + private static Map> StatusIn; + private static Map, Integer> StatusOut; - private static Map> LoginIn; - private static Map, Integer> LoginOut; + private static Map> LoginIn; + private static Map, Integer> LoginOut; - private static Map> PlayIn; - private static Map, Integer> PlayOut; + private static Map> PlayIn; + private static Map, Integer> PlayOut; - public static Map> getHandshakeIn() { - return HandshakeIn; - } + public static Map> getHandshakeIn() { + return HandshakeIn; + } - public static void setHandshakeIn(Map> handshakeIn) { - HandshakeIn = handshakeIn; - } + public static void setHandshakeIn(Map> handshakeIn) { + HandshakeIn = handshakeIn; + } - public static Map> getStatusIn() { - return StatusIn; - } + public static Map> getStatusIn() { + return StatusIn; + } - public static void setStatusIn(Map> statusIn) { - StatusIn = statusIn; - } + public static void setStatusIn(Map> statusIn) { + StatusIn = statusIn; + } - public static Map, Integer> getStatusOut() { - return StatusOut; - } + public static Map, Integer> getStatusOut() { + return StatusOut; + } - public static void setStatusOut(Map, Integer> statusOut) { - StatusOut = statusOut; - } + public static void setStatusOut(Map, Integer> statusOut) { + StatusOut = statusOut; + } - public static Map> getLoginIn() { - return LoginIn; - } + public static Map> getLoginIn() { + return LoginIn; + } - public static void setLoginIn(Map> loginIn) { - LoginIn = loginIn; - } + public static void setLoginIn(Map> loginIn) { + LoginIn = loginIn; + } - public static Map, Integer> getLoginOut() { - return LoginOut; - } + public static Map, Integer> getLoginOut() { + return LoginOut; + } - public static void setLoginOut(Map, Integer> loginOut) { - LoginOut = loginOut; - } + public static void setLoginOut(Map, Integer> loginOut) { + LoginOut = loginOut; + } - public static Map> getPlayIn() { - return PlayIn; - } + public static Map> getPlayIn() { + return PlayIn; + } - public static void setPlayIn(Map> playIn) { - PlayIn = playIn; - } + public static void setPlayIn(Map> playIn) { + PlayIn = playIn; + } - public static Map, Integer> getPlayOut() { - return PlayOut; - } + public static Map, Integer> getPlayOut() { + return PlayOut; + } - public static void setPlayOut(Map, Integer> playOut) { - PlayOut = playOut; - } + public static void setPlayOut(Map, Integer> playOut) { + PlayOut = playOut; + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketHandshakingIn.java b/src/main/java/com/loohp/limbo/server/packets/PacketHandshakingIn.java index 483517b..7f79d12 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketHandshakingIn.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketHandshakingIn.java @@ -1,69 +1,68 @@ package com.loohp.limbo.server.packets; +import com.loohp.limbo.utils.DataTypeIO; + import java.io.DataInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; -import com.loohp.limbo.utils.DataTypeIO; - public class PacketHandshakingIn extends PacketIn { - - public static enum HandshakeType { - STATUS(1), - LOGIN(2); - - int networkId; - - HandshakeType(int networkId) { - this.networkId = networkId; - } - - public int getNetworkId() { - return networkId; - } - - public static HandshakeType fromNetworkId(int networkId) { - for (HandshakeType type : HandshakeType.values()) { - if (type.getNetworkId() == networkId) { - return type; - } - } - return null; - } - } - - //============================== - - private int protocolVersion; - private String serverAddress; - private int serverPort; - private HandshakeType handshakeType; - public PacketHandshakingIn(int protocolVersion, String serverAddress, int serverPort, HandshakeType handshakeType) { - this.protocolVersion = protocolVersion; - this.serverAddress = serverAddress; - this.serverPort = serverPort; - this.handshakeType = handshakeType; - } - - public PacketHandshakingIn(DataInputStream in) throws IOException { - this(DataTypeIO.readVarInt(in), DataTypeIO.readString(in, StandardCharsets.UTF_8), in.readShort() & 0xFFFF, HandshakeType.fromNetworkId(DataTypeIO.readVarInt(in))); - } + private final int protocolVersion; - public int getProtocolVersion() { - return protocolVersion; - } + //============================== + private final String serverAddress; + private final int serverPort; + private final HandshakeType handshakeType; + public PacketHandshakingIn(int protocolVersion, String serverAddress, int serverPort, HandshakeType handshakeType) { + this.protocolVersion = protocolVersion; + this.serverAddress = serverAddress; + this.serverPort = serverPort; + this.handshakeType = handshakeType; + } - public String getServerAddress() { - return serverAddress; - } + public PacketHandshakingIn(DataInputStream in) throws IOException { + this(DataTypeIO.readVarInt(in), DataTypeIO.readString(in, StandardCharsets.UTF_8), in.readShort() & 0xFFFF, HandshakeType.fromNetworkId(DataTypeIO.readVarInt(in))); + } - public int getServerPort() { - return serverPort; - } + public int getProtocolVersion() { + return protocolVersion; + } - public HandshakeType getHandshakeType() { - return handshakeType; - } + public String getServerAddress() { + return serverAddress; + } + + public int getServerPort() { + return serverPort; + } + + public HandshakeType getHandshakeType() { + return handshakeType; + } + + public enum HandshakeType { + STATUS(1), + LOGIN(2); + + int networkId; + + HandshakeType(int networkId) { + this.networkId = networkId; + } + + public static HandshakeType fromNetworkId(int networkId) { + for (HandshakeType type : HandshakeType.values()) { + if (type.getNetworkId() == networkId) { + return type; + } + } + return null; + } + + public int getNetworkId() { + return networkId; + } + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketLoginInLoginStart.java b/src/main/java/com/loohp/limbo/server/packets/PacketLoginInLoginStart.java index 684c738..aed835b 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketLoginInLoginStart.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketLoginInLoginStart.java @@ -1,25 +1,25 @@ package com.loohp.limbo.server.packets; +import com.loohp.limbo.utils.DataTypeIO; + import java.io.DataInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; -import com.loohp.limbo.utils.DataTypeIO; - public class PacketLoginInLoginStart extends PacketIn { - - private String username; - - public PacketLoginInLoginStart(String username) { - this.username = username; - } - - public PacketLoginInLoginStart(DataInputStream in) throws IOException { - this(DataTypeIO.readString(in, StandardCharsets.UTF_8)); - } - public String getUsername() { - return username; - } + private final String username; + + public PacketLoginInLoginStart(String username) { + this.username = username; + } + + public PacketLoginInLoginStart(DataInputStream in) throws IOException { + this(DataTypeIO.readString(in, StandardCharsets.UTF_8)); + } + + public String getUsername() { + return username; + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketLoginInPluginMessaging.java b/src/main/java/com/loohp/limbo/server/packets/PacketLoginInPluginMessaging.java index 5e6e166..a9459f5 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketLoginInPluginMessaging.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketLoginInPluginMessaging.java @@ -1,43 +1,43 @@ package com.loohp.limbo.server.packets; +import com.loohp.limbo.utils.DataTypeIO; +import com.loohp.limbo.utils.NamespacedKey; + import java.io.DataInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; -import com.loohp.limbo.utils.DataTypeIO; -import com.loohp.limbo.utils.NamespacedKey; - public class PacketLoginInPluginMessaging extends PacketIn { - private int messageId; - private NamespacedKey channel; - private byte[] data; + private final int messageId; + private final NamespacedKey channel; + private final byte[] data; - public PacketLoginInPluginMessaging(int messageId, NamespacedKey channel, byte[] data) { - this.messageId = messageId; - this.channel = channel; - this.data = data; - } - - public PacketLoginInPluginMessaging(DataInputStream in, int packetLength, int packetId) throws IOException { - messageId = DataTypeIO.readVarInt(in); - String rawChannel = DataTypeIO.readString(in, StandardCharsets.UTF_8); - channel = new NamespacedKey(rawChannel); - int dataLength = packetLength - DataTypeIO.getVarIntLength(packetId) - DataTypeIO.getVarIntLength(messageId) - DataTypeIO.getStringLength(rawChannel, StandardCharsets.UTF_8); - data = new byte[dataLength]; - in.read(data); - } - - public int getMessageId() { - return messageId; - } + public PacketLoginInPluginMessaging(int messageId, NamespacedKey channel, byte[] data) { + this.messageId = messageId; + this.channel = channel; + this.data = data; + } - public NamespacedKey getChannel() { - return channel; - } + public PacketLoginInPluginMessaging(DataInputStream in, int packetLength, int packetId) throws IOException { + messageId = DataTypeIO.readVarInt(in); + String rawChannel = DataTypeIO.readString(in, StandardCharsets.UTF_8); + channel = new NamespacedKey(rawChannel); + int dataLength = packetLength - DataTypeIO.getVarIntLength(packetId) - DataTypeIO.getVarIntLength(messageId) - DataTypeIO.getStringLength(rawChannel, StandardCharsets.UTF_8); + data = new byte[dataLength]; + in.read(data); + } - public byte[] getData() { - return data; - } + public int getMessageId() { + return messageId; + } + + public NamespacedKey getChannel() { + return channel; + } + + public byte[] getData() { + return data; + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketLoginOutDisconnect.java b/src/main/java/com/loohp/limbo/server/packets/PacketLoginOutDisconnect.java index a7ee14e..067fe44 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketLoginOutDisconnect.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketLoginOutDisconnect.java @@ -1,33 +1,33 @@ package com.loohp.limbo.server.packets; +import com.loohp.limbo.utils.DataTypeIO; + import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; -import com.loohp.limbo.utils.DataTypeIO; - public class PacketLoginOutDisconnect extends PacketOut { - - private String jsonReason; - public PacketLoginOutDisconnect(String jsonReason) { - this.jsonReason = jsonReason; - } + private final String jsonReason; - public String getJsonReason() { - return jsonReason; - } + public PacketLoginOutDisconnect(String jsonReason) { + this.jsonReason = jsonReason; + } - @Override - public byte[] serializePacket() throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - output.writeByte(Packet.getLoginOut().get(getClass())); - DataTypeIO.writeString(output, jsonReason, StandardCharsets.UTF_8); - - return buffer.toByteArray(); - } + public String getJsonReason() { + return jsonReason; + } + + @Override + public byte[] serializePacket() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + DataOutputStream output = new DataOutputStream(buffer); + output.writeByte(Packet.getLoginOut().get(getClass())); + DataTypeIO.writeString(output, jsonReason, StandardCharsets.UTF_8); + + return buffer.toByteArray(); + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketLoginOutLoginSuccess.java b/src/main/java/com/loohp/limbo/server/packets/PacketLoginOutLoginSuccess.java index 12f5330..27532ab 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketLoginOutLoginSuccess.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketLoginOutLoginSuccess.java @@ -1,41 +1,41 @@ package com.loohp.limbo.server.packets; +import com.loohp.limbo.utils.DataTypeIO; + import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.UUID; -import com.loohp.limbo.utils.DataTypeIO; - public class PacketLoginOutLoginSuccess extends PacketOut { - - private UUID uuid; - private String username; - - public PacketLoginOutLoginSuccess(UUID uuid, String username) { - this.uuid = uuid; - this.username = username; - } - - public UUID getUuid() { - return uuid; - } - public String getUsername() { - return username; - } - - @Override - public byte[] serializePacket() throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - output.writeByte(Packet.getLoginOut().get(getClass())); - DataTypeIO.writeUUID(output, uuid); - DataTypeIO.writeString(output, username, StandardCharsets.UTF_8); - - return buffer.toByteArray(); - } + private final UUID uuid; + private final String username; + + public PacketLoginOutLoginSuccess(UUID uuid, String username) { + this.uuid = uuid; + this.username = username; + } + + public UUID getUuid() { + return uuid; + } + + public String getUsername() { + return username; + } + + @Override + public byte[] serializePacket() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + DataOutputStream output = new DataOutputStream(buffer); + output.writeByte(Packet.getLoginOut().get(getClass())); + DataTypeIO.writeUUID(output, uuid); + DataTypeIO.writeString(output, username, StandardCharsets.UTF_8); + + return buffer.toByteArray(); + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketLoginOutPluginMessaging.java b/src/main/java/com/loohp/limbo/server/packets/PacketLoginOutPluginMessaging.java index a5a890a..fc1ee3e 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketLoginOutPluginMessaging.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketLoginOutPluginMessaging.java @@ -1,48 +1,48 @@ package com.loohp.limbo.server.packets; +import com.loohp.limbo.utils.DataTypeIO; +import com.loohp.limbo.utils.NamespacedKey; + import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; -import com.loohp.limbo.utils.DataTypeIO; -import com.loohp.limbo.utils.NamespacedKey; - public class PacketLoginOutPluginMessaging extends PacketOut { - private int messageId; - private NamespacedKey channel; - private byte[] data; + private final int messageId; + private final NamespacedKey channel; + private final byte[] data; - public PacketLoginOutPluginMessaging(int messageId, NamespacedKey channel, byte[] data) { - this.messageId = messageId; - this.channel = channel; - this.data = data; - } - - public int getMessageId() { - return messageId; - } + public PacketLoginOutPluginMessaging(int messageId, NamespacedKey channel, byte[] data) { + this.messageId = messageId; + this.channel = channel; + this.data = data; + } - public NamespacedKey getChannel() { - return channel; - } + public int getMessageId() { + return messageId; + } - public byte[] getData() { - return data; - } + public NamespacedKey getChannel() { + return channel; + } - @Override - public byte[] serializePacket() throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - output.writeByte(Packet.getLoginOut().get(getClass())); - DataTypeIO.writeVarInt(output, messageId); - DataTypeIO.writeString(output, channel.toString(), StandardCharsets.UTF_8); - output.write(data); - - return buffer.toByteArray(); - } + public byte[] getData() { + return data; + } + + @Override + public byte[] serializePacket() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + DataOutputStream output = new DataOutputStream(buffer); + output.writeByte(Packet.getLoginOut().get(getClass())); + DataTypeIO.writeVarInt(output, messageId); + DataTypeIO.writeString(output, channel.toString(), StandardCharsets.UTF_8); + output.write(data); + + return buffer.toByteArray(); + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketOut.java b/src/main/java/com/loohp/limbo/server/packets/PacketOut.java index 77bd0f0..393d05e 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketOut.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketOut.java @@ -3,7 +3,7 @@ package com.loohp.limbo.server.packets; import java.io.IOException; public abstract class PacketOut extends Packet { - - public abstract byte[] serializePacket() throws IOException; + + public abstract byte[] serializePacket() throws IOException; } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayInChat.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayInChat.java index d14bae6..52de3f7 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayInChat.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayInChat.java @@ -1,25 +1,25 @@ package com.loohp.limbo.server.packets; +import com.loohp.limbo.utils.DataTypeIO; + import java.io.DataInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; -import com.loohp.limbo.utils.DataTypeIO; - public class PacketPlayInChat extends PacketIn { - - private String message; - - public PacketPlayInChat(String message) { - this.message = message; - } - - public PacketPlayInChat(DataInputStream in) throws IOException { - this(DataTypeIO.readString(in, StandardCharsets.UTF_8)); - } - public String getMessage() { - return message; - } + private final String message; + + public PacketPlayInChat(String message) { + this.message = message; + } + + public PacketPlayInChat(DataInputStream in) throws IOException { + this(DataTypeIO.readString(in, StandardCharsets.UTF_8)); + } + + public String getMessage() { + return message; + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayInHeldItemChange.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayInHeldItemChange.java index a8ad08a..8ccb94d 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayInHeldItemChange.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayInHeldItemChange.java @@ -5,7 +5,7 @@ import java.io.IOException; public class PacketPlayInHeldItemChange extends PacketIn { - private short slot; + private final short slot; public PacketPlayInHeldItemChange(short slot) { this.slot = slot; diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayInKeepAlive.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayInKeepAlive.java index 9995c51..3c3562f 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayInKeepAlive.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayInKeepAlive.java @@ -4,19 +4,19 @@ import java.io.DataInputStream; import java.io.IOException; public class PacketPlayInKeepAlive extends PacketIn { - - private long payload; - - public PacketPlayInKeepAlive(long payload) { - this.payload = payload; - } - - public PacketPlayInKeepAlive(DataInputStream in) throws IOException { - this(in.readLong()); - } - - public long getPayload() { - return payload; - } + + private final long payload; + + public PacketPlayInKeepAlive(long payload) { + this.payload = payload; + } + + public PacketPlayInKeepAlive(DataInputStream in) throws IOException { + this(in.readLong()); + } + + public long getPayload() { + return payload; + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayInPluginMessaging.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayInPluginMessaging.java index 5d5de1b..171a679 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayInPluginMessaging.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayInPluginMessaging.java @@ -1,36 +1,36 @@ package com.loohp.limbo.server.packets; +import com.loohp.limbo.utils.DataTypeIO; +import com.loohp.limbo.utils.NamespacedKey; + import java.io.DataInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; -import com.loohp.limbo.utils.DataTypeIO; -import com.loohp.limbo.utils.NamespacedKey; - public class PacketPlayInPluginMessaging extends PacketIn { - private NamespacedKey channel; - private byte[] data; + private final NamespacedKey channel; + private final byte[] data; - public PacketPlayInPluginMessaging(NamespacedKey channel, byte[] data) { - this.channel = channel; - this.data = data; - } - - public PacketPlayInPluginMessaging(DataInputStream in, int packetLength, int packetId) throws IOException { - String rawChannel = DataTypeIO.readString(in, StandardCharsets.UTF_8); - channel = new NamespacedKey(rawChannel); - int dataLength = packetLength - DataTypeIO.getVarIntLength(packetId) - DataTypeIO.getStringLength(rawChannel, StandardCharsets.UTF_8); - data = new byte[dataLength]; - in.read(data); - } + public PacketPlayInPluginMessaging(NamespacedKey channel, byte[] data) { + this.channel = channel; + this.data = data; + } - public NamespacedKey getChannel() { - return channel; - } + public PacketPlayInPluginMessaging(DataInputStream in, int packetLength, int packetId) throws IOException { + String rawChannel = DataTypeIO.readString(in, StandardCharsets.UTF_8); + channel = new NamespacedKey(rawChannel); + int dataLength = packetLength - DataTypeIO.getVarIntLength(packetId) - DataTypeIO.getStringLength(rawChannel, StandardCharsets.UTF_8); + data = new byte[dataLength]; + in.read(data); + } - public byte[] getData() { - return data; - } + public NamespacedKey getChannel() { + return channel; + } + + public byte[] getData() { + return data; + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayInPosition.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayInPosition.java index 05f8702..5e60bdc 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayInPosition.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayInPosition.java @@ -4,37 +4,37 @@ import java.io.DataInputStream; import java.io.IOException; public class PacketPlayInPosition extends PacketIn { - - private double x; - private double y; - private double z; - private boolean onGround; - - public PacketPlayInPosition(double x, double y, double z, boolean onGround) { - this.x = x; - this.y = y; - this.z = z; - this.onGround = onGround; - } - - public PacketPlayInPosition(DataInputStream in) throws IOException { - this(in.readDouble(), in.readDouble(), in.readDouble(), in.readBoolean()); - } - public double getX() { - return x; - } + private final double x; + private final double y; + private final double z; + private final boolean onGround; - public double getY() { - return y; - } + public PacketPlayInPosition(double x, double y, double z, boolean onGround) { + this.x = x; + this.y = y; + this.z = z; + this.onGround = onGround; + } - public double getZ() { - return z; - } + public PacketPlayInPosition(DataInputStream in) throws IOException { + this(in.readDouble(), in.readDouble(), in.readDouble(), in.readBoolean()); + } - public boolean onGround() { - return onGround; - } + public double getX() { + return x; + } + + public double getY() { + return y; + } + + public double getZ() { + return z; + } + + public boolean onGround() { + return onGround; + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayInPositionAndLook.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayInPositionAndLook.java index 36ad969..b0715ea 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayInPositionAndLook.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayInPositionAndLook.java @@ -4,49 +4,49 @@ import java.io.DataInputStream; import java.io.IOException; public class PacketPlayInPositionAndLook extends PacketIn { - - private double x; - private double y; - private double z; - private float yaw; - private float pitch; - private boolean onGround; - - public PacketPlayInPositionAndLook(double x, double y, double z, float yaw, float pitch, boolean onGround) { - this.x = x; - this.y = y; - this.z = z; - this.yaw = yaw; - this.pitch = pitch; - this.onGround = onGround; - } - - public PacketPlayInPositionAndLook(DataInputStream in) throws IOException { - this(in.readDouble(), in.readDouble(), in.readDouble(), in.readFloat(), in.readFloat(), in.readBoolean()); - } - public double getX() { - return x; - } + private final double x; + private final double y; + private final double z; + private final float yaw; + private final float pitch; + private final boolean onGround; - public double getY() { - return y; - } + public PacketPlayInPositionAndLook(double x, double y, double z, float yaw, float pitch, boolean onGround) { + this.x = x; + this.y = y; + this.z = z; + this.yaw = yaw; + this.pitch = pitch; + this.onGround = onGround; + } - public double getZ() { - return z; - } + public PacketPlayInPositionAndLook(DataInputStream in) throws IOException { + this(in.readDouble(), in.readDouble(), in.readDouble(), in.readFloat(), in.readFloat(), in.readBoolean()); + } - public float getYaw() { - return yaw; - } + public double getX() { + return x; + } - public float getPitch() { - return pitch; - } + public double getY() { + return y; + } - public boolean onGround() { - return onGround; - } + public double getZ() { + return z; + } + + public float getYaw() { + return yaw; + } + + public float getPitch() { + return pitch; + } + + public boolean onGround() { + return onGround; + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayInRotation.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayInRotation.java index 79b4d4e..911e0bd 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayInRotation.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayInRotation.java @@ -4,31 +4,31 @@ import java.io.DataInputStream; import java.io.IOException; public class PacketPlayInRotation extends PacketIn { - - private float yaw; - private float pitch; - private boolean onGround; - - public PacketPlayInRotation(float yaw, float pitch, boolean onGround) { - this.yaw = yaw; - this.pitch = pitch; - this.onGround = onGround; - } - - public PacketPlayInRotation(DataInputStream in) throws IOException { - this(in.readFloat(), in.readFloat(), in.readBoolean()); - } - public float getYaw() { - return yaw; - } + private final float yaw; + private final float pitch; + private final boolean onGround; - public float getPitch() { - return pitch; - } + public PacketPlayInRotation(float yaw, float pitch, boolean onGround) { + this.yaw = yaw; + this.pitch = pitch; + this.onGround = onGround; + } - public boolean onGround() { - return onGround; - } + public PacketPlayInRotation(DataInputStream in) throws IOException { + this(in.readFloat(), in.readFloat(), in.readBoolean()); + } + + public float getYaw() { + return yaw; + } + + public float getPitch() { + return pitch; + } + + public boolean onGround() { + return onGround; + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayInTabComplete.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayInTabComplete.java index d64aa79..c607310 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayInTabComplete.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayInTabComplete.java @@ -1,31 +1,31 @@ package com.loohp.limbo.server.packets; +import com.loohp.limbo.utils.DataTypeIO; + import java.io.DataInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; -import com.loohp.limbo.utils.DataTypeIO; - public class PacketPlayInTabComplete extends PacketIn { - private int id; - private String text; + private final int id; + private final String text; - public PacketPlayInTabComplete(int id, String text) { - this.id = id; - this.text = text; - } + public PacketPlayInTabComplete(int id, String text) { + this.id = id; + this.text = text; + } - public PacketPlayInTabComplete(DataInputStream in) throws IOException { - this(DataTypeIO.readVarInt(in), DataTypeIO.readString(in, StandardCharsets.UTF_8)); - } + public PacketPlayInTabComplete(DataInputStream in) throws IOException { + this(DataTypeIO.readVarInt(in), DataTypeIO.readString(in, StandardCharsets.UTF_8)); + } - public int getId() { - return id; - } + public int getId() { + return id; + } - public String getText() { - return text; - } + public String getText() { + return text; + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutChat.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutChat.java index 3377332..f8d8397 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutChat.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutChat.java @@ -1,48 +1,48 @@ package com.loohp.limbo.server.packets; +import com.loohp.limbo.utils.DataTypeIO; + import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.UUID; -import com.loohp.limbo.utils.DataTypeIO; - public class PacketPlayOutChat extends PacketOut { - - private String json; - private int position; - private UUID sender; - - public PacketPlayOutChat(String json, int position, UUID sender) { - this.json = json; - this.position = position; - this.sender = sender; - } - public String getJson() { - return json; - } + private final String json; + private final int position; + private final UUID sender; - public int getPosition() { - return position; - } + public PacketPlayOutChat(String json, int position, UUID sender) { + this.json = json; + this.position = position; + this.sender = sender; + } - public UUID getSender() { - return sender; - } - - @Override - public byte[] serializePacket() throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - output.writeByte(Packet.getPlayOut().get(getClass())); - DataTypeIO.writeString(output, json, StandardCharsets.UTF_8); - output.writeByte(position); - DataTypeIO.writeUUID(output, sender); - - return buffer.toByteArray(); - } + public String getJson() { + return json; + } + + public int getPosition() { + return position; + } + + public UUID getSender() { + return sender; + } + + @Override + public byte[] serializePacket() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + DataOutputStream output = new DataOutputStream(buffer); + output.writeByte(Packet.getPlayOut().get(getClass())); + DataTypeIO.writeString(output, json, StandardCharsets.UTF_8); + output.writeByte(position); + DataTypeIO.writeUUID(output, sender); + + return buffer.toByteArray(); + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutDeclareCommands.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutDeclareCommands.java index 9d2c287..b9cd6ed 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutDeclareCommands.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutDeclareCommands.java @@ -5,26 +5,26 @@ import java.io.DataOutputStream; import java.io.IOException; public class PacketPlayOutDeclareCommands extends PacketOut { - - private byte[] data; - - public PacketPlayOutDeclareCommands(byte[] data) { - this.data = data; - } - - public byte[] getData() { - return data; - } - @Override - public byte[] serializePacket() throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - output.writeByte(Packet.getPlayOut().get(getClass())); - output.write(data); - - return buffer.toByteArray(); - } + private final byte[] data; + + public PacketPlayOutDeclareCommands(byte[] data) { + this.data = data; + } + + public byte[] getData() { + return data; + } + + @Override + public byte[] serializePacket() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + DataOutputStream output = new DataOutputStream(buffer); + output.writeByte(Packet.getPlayOut().get(getClass())); + output.write(data); + + return buffer.toByteArray(); + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutDisconnect.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutDisconnect.java index 0eb0659..cc6f5d2 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutDisconnect.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutDisconnect.java @@ -1,33 +1,33 @@ package com.loohp.limbo.server.packets; +import com.loohp.limbo.utils.DataTypeIO; + import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; -import com.loohp.limbo.utils.DataTypeIO; - public class PacketPlayOutDisconnect extends PacketOut { - - private String jsonReason; - public PacketPlayOutDisconnect(String jsonReason) { - this.jsonReason = jsonReason; - } + private final String jsonReason; - public String getJsonReason() { - return jsonReason; - } + public PacketPlayOutDisconnect(String jsonReason) { + this.jsonReason = jsonReason; + } - @Override - public byte[] serializePacket() throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - output.writeByte(Packet.getPlayOut().get(getClass())); - DataTypeIO.writeString(output, jsonReason, StandardCharsets.UTF_8); - - return buffer.toByteArray(); - } + public String getJsonReason() { + return jsonReason; + } + + @Override + public byte[] serializePacket() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + DataOutputStream output = new DataOutputStream(buffer); + output.writeByte(Packet.getPlayOut().get(getClass())); + DataTypeIO.writeString(output, jsonReason, StandardCharsets.UTF_8); + + return buffer.toByteArray(); + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutEntityDestroy.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutEntityDestroy.java index 0ea22c4..c892880 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutEntityDestroy.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutEntityDestroy.java @@ -1,35 +1,35 @@ package com.loohp.limbo.server.packets; +import com.loohp.limbo.utils.DataTypeIO; + import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; -import com.loohp.limbo.utils.DataTypeIO; - public class PacketPlayOutEntityDestroy extends PacketOut { - - private int[] entityIds; - - public PacketPlayOutEntityDestroy(int... entityIds) { - this.entityIds = entityIds; - } - public int[] getEntityIds() { - return entityIds; - } - - @Override - public byte[] serializePacket() throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - output.writeByte(Packet.getPlayOut().get(getClass())); - DataTypeIO.writeVarInt(output, entityIds.length); - for (int id : entityIds) { - DataTypeIO.writeVarInt(output, id); - } - - return buffer.toByteArray(); - } + private final int[] entityIds; + + public PacketPlayOutEntityDestroy(int... entityIds) { + this.entityIds = entityIds; + } + + public int[] getEntityIds() { + return entityIds; + } + + @Override + public byte[] serializePacket() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + DataOutputStream output = new DataOutputStream(buffer); + output.writeByte(Packet.getPlayOut().get(getClass())); + DataTypeIO.writeVarInt(output, entityIds.length); + for (int id : entityIds) { + DataTypeIO.writeVarInt(output, id); + } + + return buffer.toByteArray(); + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutEntityMetadata.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutEntityMetadata.java index 0ae4671..5da5099 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutEntityMetadata.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutEntityMetadata.java @@ -1,156 +1,149 @@ package com.loohp.limbo.server.packets; +import com.loohp.limbo.entity.DataWatcher.WatchableObject; +import com.loohp.limbo.entity.DataWatcher.WatchableObjectType; +import com.loohp.limbo.entity.Entity; +import com.loohp.limbo.entity.Pose; +import com.loohp.limbo.utils.DataTypeIO; +import com.loohp.limbo.utils.Rotation3f; +import com.loohp.limbo.world.BlockPosition; +import net.md_5.bungee.chat.ComponentSerializer; + import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.lang.reflect.Field; import java.nio.charset.StandardCharsets; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.UUID; - -import com.loohp.limbo.entity.Entity; -import com.loohp.limbo.entity.Pose; -import com.loohp.limbo.entity.DataWatcher.WatchableObject; -import com.loohp.limbo.entity.DataWatcher.WatchableObjectType; -import com.loohp.limbo.utils.DataTypeIO; -import com.loohp.limbo.utils.Rotation3f; -import com.loohp.limbo.world.BlockPosition; - -import net.md_5.bungee.chat.ComponentSerializer; public class PacketPlayOutEntityMetadata extends PacketOut { - - public static final int END_OFF_METADATA = 0xff; - - private Entity entity; - public boolean allFields; - public Field[] fields; - - public PacketPlayOutEntityMetadata(Entity entity, boolean allFields, Field... fields) { - this.entity = entity; - this.allFields = allFields; - this.fields = fields; - } - - public PacketPlayOutEntityMetadata(Entity entity) { - this(entity, true); - } - public Entity getEntity() { - return entity; - } + public static final int END_OFF_METADATA = 0xff; + public boolean allFields; + public Field[] fields; + private final Entity entity; - @Override - public byte[] serializePacket() throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - output.writeByte(Packet.getPlayOut().get(getClass())); - DataTypeIO.writeVarInt(output, entity.getEntityId()); - Collection watches; - if (allFields) { - watches = new HashSet<>(entity.getDataWatcher().getWatchableObjects().values()); - } else { - watches = new HashSet<>(); - Map entries = entity.getDataWatcher().getWatchableObjects(); - for (Field field : fields) { - WatchableObject watch = entries.get(field); - if (watch != null) { - watches.add(watch); - } - } - } - - Map bitmasks = new HashMap<>(); - Iterator itr = watches.iterator(); - while (itr.hasNext()) { - WatchableObject watch = itr.next(); - if (watch.isBitmask()) { - itr.remove(); - Integer bitmask = bitmasks.get(watch.getIndex()); - if (bitmask == null) { - bitmask = 0; - } - if ((boolean) watch.getValue()) { - bitmask |= watch.getBitmask(); - } else { - bitmask &= ~watch.getBitmask(); - } - bitmasks.put(watch.getIndex(), bitmask); - } - } - for (Entry entry : bitmasks.entrySet()) { - watches.add(new WatchableObject(entry.getValue().byteValue(), entry.getKey(), WatchableObjectType.BYTE)); - } - - for (WatchableObject watch : watches) { - output.writeByte(watch.getIndex()); - if (watch.isOptional()) { - DataTypeIO.writeVarInt(output, watch.getType().getOptionalTypeId()); - output.writeBoolean(watch.getValue() != null); - } else { - DataTypeIO.writeVarInt(output, watch.getType().getTypeId()); - } - if (!watch.isOptional() || watch.getValue() != null) { - switch (watch.getType()) { - //case BLOCKID: - // break; - case POSITION: - DataTypeIO.writeBlockPosition(output, (BlockPosition) watch.getValue()); - break; - case BOOLEAN: - output.writeBoolean((boolean) watch.getValue()); - break; - case BYTE: - output.writeByte((byte) watch.getValue()); - break; - case CHAT: - DataTypeIO.writeString(output, ComponentSerializer.toString(watch.getValue()), StandardCharsets.UTF_8); - break; - //case DIRECTION: - // break; - case FLOAT: - output.writeFloat((float) watch.getValue()); - break; - //case NBT: - // break; - //case PARTICLE: - // break; - case POSE: - DataTypeIO.writeVarInt(output, ((Pose) watch.getValue()).getId()); - break; - case ROTATION: - Rotation3f rotation = (Rotation3f) watch.getValue(); - output.writeFloat((float) rotation.getX()); - output.writeFloat((float) rotation.getY()); - output.writeFloat((float) rotation.getZ()); - break; - //case SLOT: - // break; - case STRING: - DataTypeIO.writeString(output, watch.getValue().toString(), StandardCharsets.UTF_8); - break; - case UUID: - DataTypeIO.writeUUID(output, (UUID) watch.getValue()); - break; - case VARINT: - DataTypeIO.writeVarInt(output, (int) watch.getValue()); - break; - //case VILLAGER_DATA: - // break; - default: - break; - } - } - } - output.writeByte(END_OFF_METADATA); - - return buffer.toByteArray(); - } + public PacketPlayOutEntityMetadata(Entity entity, boolean allFields, Field... fields) { + this.entity = entity; + this.allFields = allFields; + this.fields = fields; + } + + public PacketPlayOutEntityMetadata(Entity entity) { + this(entity, true); + } + + public Entity getEntity() { + return entity; + } + + @Override + public byte[] serializePacket() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + DataOutputStream output = new DataOutputStream(buffer); + output.writeByte(Packet.getPlayOut().get(getClass())); + DataTypeIO.writeVarInt(output, entity.getEntityId()); + Collection watches; + if (allFields) { + watches = new HashSet<>(entity.getDataWatcher().getWatchableObjects().values()); + } else { + watches = new HashSet<>(); + Map entries = entity.getDataWatcher().getWatchableObjects(); + for (Field field : fields) { + WatchableObject watch = entries.get(field); + if (watch != null) { + watches.add(watch); + } + } + } + + Map bitmasks = new HashMap<>(); + Iterator itr = watches.iterator(); + while (itr.hasNext()) { + WatchableObject watch = itr.next(); + if (watch.isBitmask()) { + itr.remove(); + Integer bitmask = bitmasks.get(watch.getIndex()); + if (bitmask == null) { + bitmask = 0; + } + if ((boolean) watch.getValue()) { + bitmask |= watch.getBitmask(); + } else { + bitmask &= ~watch.getBitmask(); + } + bitmasks.put(watch.getIndex(), bitmask); + } + } + for (Entry entry : bitmasks.entrySet()) { + watches.add(new WatchableObject(entry.getValue().byteValue(), entry.getKey(), WatchableObjectType.BYTE)); + } + + for (WatchableObject watch : watches) { + output.writeByte(watch.getIndex()); + if (watch.isOptional()) { + DataTypeIO.writeVarInt(output, watch.getType().getOptionalTypeId()); + output.writeBoolean(watch.getValue() != null); + } else { + DataTypeIO.writeVarInt(output, watch.getType().getTypeId()); + } + if (!watch.isOptional() || watch.getValue() != null) { + switch (watch.getType()) { + //case BLOCKID: + // break; + case POSITION: + DataTypeIO.writeBlockPosition(output, (BlockPosition) watch.getValue()); + break; + case BOOLEAN: + output.writeBoolean((boolean) watch.getValue()); + break; + case BYTE: + output.writeByte((byte) watch.getValue()); + break; + case CHAT: + DataTypeIO.writeString(output, ComponentSerializer.toString(watch.getValue()), StandardCharsets.UTF_8); + break; + //case DIRECTION: + // break; + case FLOAT: + output.writeFloat((float) watch.getValue()); + break; + //case NBT: + // break; + //case PARTICLE: + // break; + case POSE: + DataTypeIO.writeVarInt(output, ((Pose) watch.getValue()).getId()); + break; + case ROTATION: + Rotation3f rotation = (Rotation3f) watch.getValue(); + output.writeFloat((float) rotation.getX()); + output.writeFloat((float) rotation.getY()); + output.writeFloat((float) rotation.getZ()); + break; + //case SLOT: + // break; + case STRING: + DataTypeIO.writeString(output, watch.getValue().toString(), StandardCharsets.UTF_8); + break; + case UUID: + DataTypeIO.writeUUID(output, (UUID) watch.getValue()); + break; + case VARINT: + DataTypeIO.writeVarInt(output, (int) watch.getValue()); + break; + //case VILLAGER_DATA: + // break; + default: + break; + } + } + } + output.writeByte(END_OFF_METADATA); + + return buffer.toByteArray(); + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutGameState.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutGameState.java index bcc68f6..3a6c18f 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutGameState.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutGameState.java @@ -6,32 +6,32 @@ import java.io.IOException; public class PacketPlayOutGameState extends PacketOut { - private int reason; - private float value; + private final int reason; + private final float value; - public PacketPlayOutGameState(int reason, float value) { - this.reason = reason; - this.value = value; - } + public PacketPlayOutGameState(int reason, float value) { + this.reason = reason; + this.value = value; + } - public int getReason() { - return reason; - } + public int getReason() { + return reason; + } - public float getValue() { - return value; - } + public float getValue() { + return value; + } - @Override - public byte[] serializePacket() throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - output.writeByte(Packet.getPlayOut().get(getClass())); - output.writeByte(reason); - output.writeFloat(value); - - return buffer.toByteArray(); - } + @Override + public byte[] serializePacket() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + DataOutputStream output = new DataOutputStream(buffer); + output.writeByte(Packet.getPlayOut().get(getClass())); + output.writeByte(reason); + output.writeFloat(value); + + return buffer.toByteArray(); + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutKeepAlive.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutKeepAlive.java index 2f98f81..8c5d377 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutKeepAlive.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutKeepAlive.java @@ -5,26 +5,26 @@ import java.io.DataOutputStream; import java.io.IOException; public class PacketPlayOutKeepAlive extends PacketOut { - - long payload; - - public PacketPlayOutKeepAlive(long payload) { - this.payload = payload; - } - - public long getPayload() { - return payload; - } - - @Override - public byte[] serializePacket() throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - output.writeByte(Packet.getPlayOut().get(getClass())); - output.writeLong(payload); - - return buffer.toByteArray(); - } + + long payload; + + public PacketPlayOutKeepAlive(long payload) { + this.payload = payload; + } + + public long getPayload() { + return payload; + } + + @Override + public byte[] serializePacket() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + DataOutputStream output = new DataOutputStream(buffer); + output.writeByte(Packet.getPlayOut().get(getClass())); + output.writeLong(payload); + + return buffer.toByteArray(); + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutLightUpdate.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutLightUpdate.java index afaca4c..a907a92 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutLightUpdate.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutLightUpdate.java @@ -1,111 +1,111 @@ package com.loohp.limbo.server.packets; +import com.loohp.limbo.utils.DataTypeIO; + import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.List; -import com.loohp.limbo.utils.DataTypeIO; - public class PacketPlayOutLightUpdate extends PacketOut { - private int chunkX; - private int chunkZ; - private boolean trustEdges; - private int skyLightBitMask; - private int blockLightBitMask; - private List skylightArrays; - private List blocklightArrays; + private final int chunkX; + private final int chunkZ; + private final boolean trustEdges; + private int skyLightBitMask; + private int blockLightBitMask; + private final List skylightArrays; + private final List blocklightArrays; - public PacketPlayOutLightUpdate(int chunkX, int chunkZ, boolean trustEdges, List skylightArrays, List blocklightArrays) { - this.chunkX = chunkX; - this.chunkZ = chunkZ; - this.trustEdges = trustEdges; - this.skylightArrays = skylightArrays; - this.blocklightArrays = blocklightArrays; - - skyLightBitMask = 0; - for (int i = Math.min(17, skylightArrays.size() - 1); i >= 0; i--) { - skyLightBitMask = skyLightBitMask >> 1; - if (skylightArrays.get(i) != null) { - skyLightBitMask |= 131072; - } - } - - blockLightBitMask = 0; - for (int i = Math.min(17, blocklightArrays.size() - 1); i >= 0; i--) { - blockLightBitMask = blockLightBitMask >> 1; - if (blocklightArrays.get(i) != null) { - blockLightBitMask |= 131072; - } - } - } + public PacketPlayOutLightUpdate(int chunkX, int chunkZ, boolean trustEdges, List skylightArrays, List blocklightArrays) { + this.chunkX = chunkX; + this.chunkZ = chunkZ; + this.trustEdges = trustEdges; + this.skylightArrays = skylightArrays; + this.blocklightArrays = blocklightArrays; - public int getChunkX() { - return chunkX; - } + skyLightBitMask = 0; + for (int i = Math.min(17, skylightArrays.size() - 1); i >= 0; i--) { + skyLightBitMask = skyLightBitMask >> 1; + if (skylightArrays.get(i) != null) { + skyLightBitMask |= 131072; + } + } - public int getChunkZ() { - return chunkZ; - } + blockLightBitMask = 0; + for (int i = Math.min(17, blocklightArrays.size() - 1); i >= 0; i--) { + blockLightBitMask = blockLightBitMask >> 1; + if (blocklightArrays.get(i) != null) { + blockLightBitMask |= 131072; + } + } + } - public boolean isTrustEdges() { - return trustEdges; - } + public int getChunkX() { + return chunkX; + } - public int getSkyLightBitMask() { - return skyLightBitMask; - } + public int getChunkZ() { + return chunkZ; + } - public int getBlockLightBitMask() { - return blockLightBitMask; - } + public boolean isTrustEdges() { + return trustEdges; + } - public List getSkylightArrays() { - return skylightArrays; - } + public int getSkyLightBitMask() { + return skyLightBitMask; + } - public List getBlocklightArrays() { - return blocklightArrays; - } + public int getBlockLightBitMask() { + return blockLightBitMask; + } - @Override - public byte[] serializePacket() throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - output.writeByte(Packet.getPlayOut().get(getClass())); - DataTypeIO.writeVarInt(output, chunkX); - DataTypeIO.writeVarInt(output, chunkZ); - output.writeBoolean(trustEdges); - DataTypeIO.writeVarInt(output, skyLightBitMask); - DataTypeIO.writeVarInt(output, blockLightBitMask); - DataTypeIO.writeVarInt(output, ~skyLightBitMask & 262143); - DataTypeIO.writeVarInt(output, ~blockLightBitMask & 262143); - - for (int i = skylightArrays.size() - 1; i >= 0; i--) { - Byte[] array = skylightArrays.get(i); - if (array != null) { - DataTypeIO.writeVarInt(output, 2048); - //System.out.println(Arrays.toString(ArrayUtils.toPrimitive(array))); - for (int u = 0; u < array.length; u++) { - output.writeByte(array[u]); - } - } - } - - for (int i = blocklightArrays.size() - 1; i >= 0; i--) { - Byte[] array = blocklightArrays.get(i); - if (array != null) { - DataTypeIO.writeVarInt(output, 2048); - //System.out.println(Arrays.toString(ArrayUtils.toPrimitive(array))); - for (int u = 0; u < array.length; u++) { - output.writeByte(array[u]); - } - } - } - - return buffer.toByteArray(); - } + public List getSkylightArrays() { + return skylightArrays; + } + + public List getBlocklightArrays() { + return blocklightArrays; + } + + @Override + public byte[] serializePacket() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + DataOutputStream output = new DataOutputStream(buffer); + output.writeByte(Packet.getPlayOut().get(getClass())); + DataTypeIO.writeVarInt(output, chunkX); + DataTypeIO.writeVarInt(output, chunkZ); + output.writeBoolean(trustEdges); + DataTypeIO.writeVarInt(output, skyLightBitMask); + DataTypeIO.writeVarInt(output, blockLightBitMask); + DataTypeIO.writeVarInt(output, ~skyLightBitMask & 262143); + DataTypeIO.writeVarInt(output, ~blockLightBitMask & 262143); + + for (int i = skylightArrays.size() - 1; i >= 0; i--) { + Byte[] array = skylightArrays.get(i); + if (array != null) { + DataTypeIO.writeVarInt(output, 2048); + //System.out.println(Arrays.toString(ArrayUtils.toPrimitive(array))); + for (int u = 0; u < array.length; u++) { + output.writeByte(array[u]); + } + } + } + + for (int i = blocklightArrays.size() - 1; i >= 0; i--) { + Byte[] array = blocklightArrays.get(i); + if (array != null) { + DataTypeIO.writeVarInt(output, 2048); + //System.out.println(Arrays.toString(ArrayUtils.toPrimitive(array))); + for (int u = 0; u < array.length; u++) { + output.writeByte(array[u]); + } + } + } + + return buffer.toByteArray(); + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutLogin.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutLogin.java index d3f06c2..322c32e 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutLogin.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutLogin.java @@ -1,146 +1,145 @@ package com.loohp.limbo.server.packets; -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; - import com.loohp.limbo.utils.DataTypeIO; import com.loohp.limbo.utils.GameMode; import com.loohp.limbo.utils.NamespacedKey; import com.loohp.limbo.world.Environment; import com.loohp.limbo.world.World; - import net.querz.nbt.tag.CompoundTag; import net.querz.nbt.tag.ListTag; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + public class PacketPlayOutLogin extends PacketOut { - - private int entityId; - private boolean isHardcore; - private GameMode gamemode; - private String[] worldsNames; - private CompoundTag dimensionCodec; - private Environment dimension; - private String worldName; - private long hashedSeed; - private byte maxPlayers; - private int viewDistance; - private boolean reducedDebugInfo; - private boolean enableRespawnScreen; - private boolean isDebug; - private boolean isFlat; - public PacketPlayOutLogin(int entityId, boolean isHardcore, GameMode gamemode, - String[] worldsNames, CompoundTag dimensionCodec, World world, long hashedSeed, - byte maxPlayers, int viewDistance, boolean reducedDebugInfo, boolean enableRespawnScreen, boolean isDebug, - boolean isFlat) { - this.entityId = entityId; - this.isHardcore = isHardcore; - this.gamemode = gamemode; - this.worldsNames = worldsNames; - this.dimensionCodec = dimensionCodec; - this.dimension = world.getEnvironment(); - this.worldName = new NamespacedKey(world.getName()).toString(); - this.hashedSeed = hashedSeed; - this.maxPlayers = maxPlayers; - this.viewDistance = viewDistance; - this.reducedDebugInfo = reducedDebugInfo; - this.enableRespawnScreen = enableRespawnScreen; - this.isDebug = isDebug; - this.isFlat = isFlat; - } + private final int entityId; + private final boolean isHardcore; + private final GameMode gamemode; + private final String[] worldsNames; + private final CompoundTag dimensionCodec; + private final Environment dimension; + private final String worldName; + private final long hashedSeed; + private final byte maxPlayers; + private final int viewDistance; + private final boolean reducedDebugInfo; + private final boolean enableRespawnScreen; + private final boolean isDebug; + private final boolean isFlat; - public int getEntityId() { - return entityId; - } + public PacketPlayOutLogin(int entityId, boolean isHardcore, GameMode gamemode, + String[] worldsNames, CompoundTag dimensionCodec, World world, long hashedSeed, + byte maxPlayers, int viewDistance, boolean reducedDebugInfo, boolean enableRespawnScreen, boolean isDebug, + boolean isFlat) { + this.entityId = entityId; + this.isHardcore = isHardcore; + this.gamemode = gamemode; + this.worldsNames = worldsNames; + this.dimensionCodec = dimensionCodec; + this.dimension = world.getEnvironment(); + this.worldName = new NamespacedKey(world.getName()).toString(); + this.hashedSeed = hashedSeed; + this.maxPlayers = maxPlayers; + this.viewDistance = viewDistance; + this.reducedDebugInfo = reducedDebugInfo; + this.enableRespawnScreen = enableRespawnScreen; + this.isDebug = isDebug; + this.isFlat = isFlat; + } - public boolean isHardcore() { - return isHardcore; - } + public int getEntityId() { + return entityId; + } - public GameMode getGamemode() { - return gamemode; - } + public boolean isHardcore() { + return isHardcore; + } - public String[] getWorldsNames() { - return worldsNames; - } + public GameMode getGamemode() { + return gamemode; + } - public CompoundTag getDimensionCodec() { - return dimensionCodec; - } + public String[] getWorldsNames() { + return worldsNames; + } - public Environment getDimension() { - return dimension; - } + public CompoundTag getDimensionCodec() { + return dimensionCodec; + } - public String getWorldName() { - return worldName; - } + public Environment getDimension() { + return dimension; + } - public long getHashedSeed() { - return hashedSeed; - } + public String getWorldName() { + return worldName; + } - public byte getMaxPlayers() { - return maxPlayers; - } + public long getHashedSeed() { + return hashedSeed; + } - public int getViewDistance() { - return viewDistance; - } + public byte getMaxPlayers() { + return maxPlayers; + } - public boolean isReducedDebugInfo() { - return reducedDebugInfo; - } + public int getViewDistance() { + return viewDistance; + } - public boolean isEnableRespawnScreen() { - return enableRespawnScreen; - } + public boolean isReducedDebugInfo() { + return reducedDebugInfo; + } - public boolean isDebug() { - return isDebug; - } + public boolean isEnableRespawnScreen() { + return enableRespawnScreen; + } - public boolean isFlat() { - return isFlat; - } - - @Override - public byte[] serializePacket() throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - output.writeByte(Packet.getPlayOut().get(getClass())); - output.writeInt(entityId); - output.writeBoolean(isHardcore); + public boolean isDebug() { + return isDebug; + } + + public boolean isFlat() { + return isFlat; + } + + @Override + public byte[] serializePacket() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + DataOutputStream output = new DataOutputStream(buffer); + output.writeByte(Packet.getPlayOut().get(getClass())); + output.writeInt(entityId); + output.writeBoolean(isHardcore); output.writeByte((byte) gamemode.getId()); - output.writeByte((byte) gamemode.getId()); - DataTypeIO.writeVarInt(output, worldsNames.length); - for (int u = 0; u < worldsNames.length; u++) { - DataTypeIO.writeString(output, worldsNames[u], StandardCharsets.UTF_8); - } - DataTypeIO.writeCompoundTag(output, dimensionCodec); - CompoundTag tag = null; - ListTag list = dimensionCodec.getCompoundTag("minecraft:dimension_type").getListTag("value").asCompoundTagList(); - for (CompoundTag each : list) { - if (each.getString("name").equals(dimension.getNamespacedKey().toString())) { - tag = each.getCompoundTag("element"); - break; - } - } - DataTypeIO.writeCompoundTag(output, tag != null ? tag : list.get(0)); - DataTypeIO.writeString(output, worldName, StandardCharsets.UTF_8); - output.writeLong(hashedSeed); - DataTypeIO.writeVarInt(output, maxPlayers); - DataTypeIO.writeVarInt(output, viewDistance); - output.writeBoolean(reducedDebugInfo); - output.writeBoolean(enableRespawnScreen); - output.writeBoolean(isDebug); - output.writeBoolean(isFlat); - - return buffer.toByteArray(); - } + output.writeByte((byte) gamemode.getId()); + DataTypeIO.writeVarInt(output, worldsNames.length); + for (int u = 0; u < worldsNames.length; u++) { + DataTypeIO.writeString(output, worldsNames[u], StandardCharsets.UTF_8); + } + DataTypeIO.writeCompoundTag(output, dimensionCodec); + CompoundTag tag = null; + ListTag list = dimensionCodec.getCompoundTag("minecraft:dimension_type").getListTag("value").asCompoundTagList(); + for (CompoundTag each : list) { + if (each.getString("name").equals(dimension.getNamespacedKey().toString())) { + tag = each.getCompoundTag("element"); + break; + } + } + DataTypeIO.writeCompoundTag(output, tag != null ? tag : list.get(0)); + DataTypeIO.writeString(output, worldName, StandardCharsets.UTF_8); + output.writeLong(hashedSeed); + DataTypeIO.writeVarInt(output, maxPlayers); + DataTypeIO.writeVarInt(output, viewDistance); + output.writeBoolean(reducedDebugInfo); + output.writeBoolean(enableRespawnScreen); + output.writeBoolean(isDebug); + output.writeBoolean(isFlat); + + return buffer.toByteArray(); + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutMapChunk.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutMapChunk.java index cb8db75..dd85cd9 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutMapChunk.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutMapChunk.java @@ -1,116 +1,111 @@ package com.loohp.limbo.server.packets; -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.BitSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - import com.loohp.limbo.utils.BitsUtils; import com.loohp.limbo.utils.DataTypeIO; import com.loohp.limbo.world.Environment; import com.loohp.limbo.world.GeneratedBlockDataMappings; - import net.querz.mca.Chunk; import net.querz.mca.Section; import net.querz.nbt.tag.CompoundTag; import net.querz.nbt.tag.ListTag; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.*; + public class PacketPlayOutMapChunk extends PacketOut { - private int chunkX; - private int chunkZ; - private Chunk chunk; - private Environment environment; - - public PacketPlayOutMapChunk(int chunkX, int chunkZ, Chunk chunk, Environment environment) { - this.chunkX = chunkX; - this.chunkZ = chunkZ; - this.chunk = chunk; - this.environment = environment; - } - - @Deprecated - public PacketPlayOutMapChunk(int chunkX, int chunkZ, Chunk chunk) { - this(chunkZ, chunkZ, chunk, Environment.NORMAL); - } + private final int chunkX; + private final int chunkZ; + private final Chunk chunk; + private final Environment environment; - public Chunk getChunk() { - return chunk; - } - - public int getChunkX() { - return chunkX; - } + public PacketPlayOutMapChunk(int chunkX, int chunkZ, Chunk chunk, Environment environment) { + this.chunkX = chunkX; + this.chunkZ = chunkZ; + this.chunk = chunk; + this.environment = environment; + } - public int getChunkZ() { - return chunkZ; - } - - public Environment getEnvironment() { - return environment; - } + @Deprecated + public PacketPlayOutMapChunk(int chunkX, int chunkZ, Chunk chunk) { + this(chunkZ, chunkZ, chunk, Environment.NORMAL); + } - @Override - public byte[] serializePacket() throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - output.writeByte(Packet.getPlayOut().get(getClass())); - - output.writeInt(chunkX); - output.writeInt(chunkZ); - output.writeBoolean(true); - int bitmask = 0; - for (int i = 0; i < 16; i++) { - Section section = chunk.getSection(i); - if (section != null) { - bitmask = bitmask | (int) Math.pow(2, i); - } - } - DataTypeIO.writeVarInt(output, bitmask); - DataTypeIO.writeCompoundTag(output, chunk.getHeightMaps()); - - DataTypeIO.writeVarInt(output, 1024); - int biome; - if (environment.equals(Environment.END)) { - biome = 9; //the_end - } else if (environment.equals(Environment.NETHER)) { - biome = 8; //nether_waste - } else if (environment.equals(Environment.NORMAL)) { - biome = 1; //plains - } else { - biome = 1; //plains - } - for (int i = 0; i < 1024; i++) { - DataTypeIO.writeVarInt(output, biome); - } - - ByteArrayOutputStream dataBuffer = new ByteArrayOutputStream(); - DataOutputStream dataOut = new DataOutputStream(dataBuffer); - for (int i = 0; i < 16; i++) { - Section section = chunk.getSection(i); - if (section != null) { - int counter = 0; - for (int x = 0; x < 16; x++) { - for (int z = 0; z < 16; z++) { - for (int y = 0; y < 16; y++) { - CompoundTag tag = section.getBlockStateAt(x, y, z); - if (tag != null && !tag.getString("Name").equals("minecraft:air")) { - counter++; - } - } - } - } - dataOut.writeShort(counter); + public Chunk getChunk() { + return chunk; + } - int newBits = 32 - Integer.numberOfLeadingZeros(section.getPalette().size() - 1); - newBits = Math.max(newBits, 4); - //Limbo.getInstance().getConsole().sendMessage(i + " " + newBits); - if (newBits <= 8) { + public int getChunkX() { + return chunkX; + } + + public int getChunkZ() { + return chunkZ; + } + + public Environment getEnvironment() { + return environment; + } + + @Override + public byte[] serializePacket() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + DataOutputStream output = new DataOutputStream(buffer); + output.writeByte(Packet.getPlayOut().get(getClass())); + + output.writeInt(chunkX); + output.writeInt(chunkZ); + output.writeBoolean(true); + int bitmask = 0; + for (int i = 0; i < 16; i++) { + Section section = chunk.getSection(i); + if (section != null) { + bitmask = bitmask | (int) Math.pow(2, i); + } + } + DataTypeIO.writeVarInt(output, bitmask); + DataTypeIO.writeCompoundTag(output, chunk.getHeightMaps()); + + DataTypeIO.writeVarInt(output, 1024); + int biome; + if (environment.equals(Environment.END)) { + biome = 9; //the_end + } else if (environment.equals(Environment.NETHER)) { + biome = 8; //nether_waste + } else if (environment.equals(Environment.NORMAL)) { + biome = 1; //plains + } else { + biome = 1; //plains + } + for (int i = 0; i < 1024; i++) { + DataTypeIO.writeVarInt(output, biome); + } + + ByteArrayOutputStream dataBuffer = new ByteArrayOutputStream(); + DataOutputStream dataOut = new DataOutputStream(dataBuffer); + for (int i = 0; i < 16; i++) { + Section section = chunk.getSection(i); + if (section != null) { + int counter = 0; + for (int x = 0; x < 16; x++) { + for (int z = 0; z < 16; z++) { + for (int y = 0; y < 16; y++) { + CompoundTag tag = section.getBlockStateAt(x, y, z); + if (tag != null && !tag.getString("Name").equals("minecraft:air")) { + counter++; + } + } + } + } + dataOut.writeShort(counter); + + int newBits = 32 - Integer.numberOfLeadingZeros(section.getPalette().size() - 1); + newBits = Math.max(newBits, 4); + //Limbo.getInstance().getConsole().sendMessage(i + " " + newBits); + if (newBits <= 8) { /* if (newBits == 4) { dataOut.writeByte(4); @@ -120,92 +115,92 @@ public class PacketPlayOutMapChunk extends PacketOut { dataOut.writeByte(8); } */ - dataOut.writeByte(newBits); - - DataTypeIO.writeVarInt(dataOut, section.getPalette().size()); - //Limbo.getInstance().getConsole().sendMessage(section.getPalette().size()); - Iterator itr1 = section.getPalette().iterator(); - //Limbo.getInstance().getConsole().sendMessage("Nonnull -> " + i + " " + newBits); - while (itr1.hasNext()) { - CompoundTag tag = itr1.next(); - DataTypeIO.writeVarInt(dataOut, GeneratedBlockDataMappings.getGlobalPaletteIDFromState(tag)); - //Limbo.getInstance().getConsole().sendMessage(tag + " -> " + GeneratedDataUtils.getGlobalPaletteIDFromState(tag)); - } - - BitSet bits = BitSet.valueOf(section.getBlockStates()); - int shift = 64 % newBits; - int longsNeeded = (int) Math.ceil(4096 / (double) (64 / newBits)); - for (int u = 64; u <= bits.length(); u += 64) { - bits = BitsUtils.shiftAfter(bits, u - shift, shift); - } - - long[] formattedLongs = bits.toLongArray(); - //Limbo.getInstance().getConsole().sendMessage(longsNeeded + ""); - - DataTypeIO.writeVarInt(dataOut, longsNeeded); - for (int u = 0; u < longsNeeded; u++) { - if (u < formattedLongs.length) { - dataOut.writeLong(formattedLongs[u]); - } else { - dataOut.writeLong(0); - } - //Limbo.getInstance().getConsole().sendMessage(Arrays.toString(section.getBlockStates())); - } - } else { - try { - dataOut.writeByte(15); - section.getBlockStates(); - int longsNeeded = 1024; - List list = new LinkedList<>(); - for (int y = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { - for (int x = 0; x < 16; x++) { - list.add(GeneratedBlockDataMappings.getGlobalPaletteIDFromState(section.getBlockStateAt(x, y, z))); - } - } - } - List globalLongs = new ArrayList<>(); - long currentLong = 0; - int pos = 0; - int u = 0; - while (pos < longsNeeded) { - if (u == 3) { - globalLongs.add(currentLong); - currentLong = 0; - u = 0; - pos++; - } else { - u++; - } - int id = list.isEmpty() ? 0 : list.remove(0); - currentLong = currentLong << 15; - currentLong |= (long) id; - } - DataTypeIO.writeVarInt(dataOut, longsNeeded); - for (int j = 0; j < longsNeeded; j++) { - if (j < globalLongs.size()) { - dataOut.writeLong(globalLongs.get(j)); - } else { - dataOut.writeLong(0); - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } - byte[] data = dataBuffer.toByteArray(); - DataTypeIO.writeVarInt(output, data.length); - output.write(data); - - ListTag tileEntities = chunk.getTileEntities(); - DataTypeIO.writeVarInt(output, tileEntities.size()); - for (CompoundTag each : tileEntities) { - DataTypeIO.writeCompoundTag(output, each); - } - - return buffer.toByteArray(); - } + dataOut.writeByte(newBits); + + DataTypeIO.writeVarInt(dataOut, section.getPalette().size()); + //Limbo.getInstance().getConsole().sendMessage(section.getPalette().size()); + Iterator itr1 = section.getPalette().iterator(); + //Limbo.getInstance().getConsole().sendMessage("Nonnull -> " + i + " " + newBits); + while (itr1.hasNext()) { + CompoundTag tag = itr1.next(); + DataTypeIO.writeVarInt(dataOut, GeneratedBlockDataMappings.getGlobalPaletteIDFromState(tag)); + //Limbo.getInstance().getConsole().sendMessage(tag + " -> " + GeneratedDataUtils.getGlobalPaletteIDFromState(tag)); + } + + BitSet bits = BitSet.valueOf(section.getBlockStates()); + int shift = 64 % newBits; + int longsNeeded = (int) Math.ceil(4096 / (double) (64 / newBits)); + for (int u = 64; u <= bits.length(); u += 64) { + bits = BitsUtils.shiftAfter(bits, u - shift, shift); + } + + long[] formattedLongs = bits.toLongArray(); + //Limbo.getInstance().getConsole().sendMessage(longsNeeded + ""); + + DataTypeIO.writeVarInt(dataOut, longsNeeded); + for (int u = 0; u < longsNeeded; u++) { + if (u < formattedLongs.length) { + dataOut.writeLong(formattedLongs[u]); + } else { + dataOut.writeLong(0); + } + //Limbo.getInstance().getConsole().sendMessage(Arrays.toString(section.getBlockStates())); + } + } else { + try { + dataOut.writeByte(15); + section.getBlockStates(); + int longsNeeded = 1024; + List list = new LinkedList<>(); + for (int y = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++) { + list.add(GeneratedBlockDataMappings.getGlobalPaletteIDFromState(section.getBlockStateAt(x, y, z))); + } + } + } + List globalLongs = new ArrayList<>(); + long currentLong = 0; + int pos = 0; + int u = 0; + while (pos < longsNeeded) { + if (u == 3) { + globalLongs.add(currentLong); + currentLong = 0; + u = 0; + pos++; + } else { + u++; + } + int id = list.isEmpty() ? 0 : list.remove(0); + currentLong = currentLong << 15; + currentLong |= id; + } + DataTypeIO.writeVarInt(dataOut, longsNeeded); + for (int j = 0; j < longsNeeded; j++) { + if (j < globalLongs.size()) { + dataOut.writeLong(globalLongs.get(j)); + } else { + dataOut.writeLong(0); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + byte[] data = dataBuffer.toByteArray(); + DataTypeIO.writeVarInt(output, data.length); + output.write(data); + + ListTag tileEntities = chunk.getTileEntities(); + DataTypeIO.writeVarInt(output, tileEntities.size()); + for (CompoundTag each : tileEntities) { + DataTypeIO.writeCompoundTag(output, each); + } + + return buffer.toByteArray(); + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutPlayerAbilities.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutPlayerAbilities.java index db9f172..4572a32 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutPlayerAbilities.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutPlayerAbilities.java @@ -5,62 +5,61 @@ import java.io.DataOutputStream; import java.io.IOException; public class PacketPlayOutPlayerAbilities extends PacketOut { - - public enum PlayerAbilityFlags { - INVULNERABLE(0x01), - FLY(0x02), - ALLOW_FLYING(0x04), - CREATIVE(0x08); - - int bitvalue; - - PlayerAbilityFlags(int bitvalue) { - this.bitvalue = bitvalue; - } - - public int getValue() { - return bitvalue; - } - } - private PlayerAbilityFlags[] flags; - private float flySpeed; - private float fieldOfField; + private final PlayerAbilityFlags[] flags; + private final float flySpeed; + private final float fieldOfField; + public PacketPlayOutPlayerAbilities(float flySpeed, float fieldOfField, PlayerAbilityFlags... flags) { + this.flags = flags; + this.flySpeed = flySpeed; + this.fieldOfField = fieldOfField; + } - public PacketPlayOutPlayerAbilities(float flySpeed, float fieldOfField, PlayerAbilityFlags... flags) { - this.flags = flags; - this.flySpeed = flySpeed; - this.fieldOfField = fieldOfField; - } + public PlayerAbilityFlags[] getFlags() { + return flags; + } - public PlayerAbilityFlags[] getFlags() { - return flags; - } + public float getFlySpeed() { + return flySpeed; + } - public float getFlySpeed() { - return flySpeed; - } + public float getFieldOfField() { + return fieldOfField; + } - public float getFieldOfField() { - return fieldOfField; - } - - @Override - public byte[] serializePacket() throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - output.writeByte(Packet.getPlayOut().get(getClass())); - int value = 0; - for (PlayerAbilityFlags flag : flags) { - value = value | flag.getValue(); - } - - output.writeByte(value); - output.writeFloat(flySpeed); - output.writeFloat(fieldOfField); - - return buffer.toByteArray(); - } + @Override + public byte[] serializePacket() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + DataOutputStream output = new DataOutputStream(buffer); + output.writeByte(Packet.getPlayOut().get(getClass())); + int value = 0; + for (PlayerAbilityFlags flag : flags) { + value = value | flag.getValue(); + } + + output.writeByte(value); + output.writeFloat(flySpeed); + output.writeFloat(fieldOfField); + + return buffer.toByteArray(); + } + + public enum PlayerAbilityFlags { + INVULNERABLE(0x01), + FLY(0x02), + ALLOW_FLYING(0x04), + CREATIVE(0x08); + + int bitvalue; + + PlayerAbilityFlags(int bitvalue) { + this.bitvalue = bitvalue; + } + + public int getValue() { + return bitvalue; + } + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutPlayerInfo.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutPlayerInfo.java index 58d8c95..da9a845 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutPlayerInfo.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutPlayerInfo.java @@ -1,5 +1,9 @@ package com.loohp.limbo.server.packets; +import com.loohp.limbo.server.packets.PacketPlayOutPlayerInfo.PlayerInfoData.PlayerInfoDataAddPlayer; +import com.loohp.limbo.utils.DataTypeIO; +import com.loohp.limbo.utils.GameMode; + import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; @@ -7,162 +11,157 @@ import java.nio.charset.StandardCharsets; import java.util.Optional; import java.util.UUID; -import com.loohp.limbo.server.packets.PacketPlayOutPlayerInfo.PlayerInfoData.PlayerInfoDataAddPlayer; -import com.loohp.limbo.utils.DataTypeIO; -import com.loohp.limbo.utils.GameMode; - public class PacketPlayOutPlayerInfo extends PacketOut { - public enum PlayerInfoAction { - ADD_PLAYER(0), UPDATE_GAMEMODE(1), UPDATE_LATENCY(2), UPDATE_DISPLAY_NAME(3), REMOVE_PLAYER(4); + private final PlayerInfoAction action; + private final UUID uuid; + private final PlayerInfoData data; + public PacketPlayOutPlayerInfo(PlayerInfoAction action, UUID uuid, PlayerInfoData data) { + this.action = action; + this.uuid = uuid; + this.data = data; + } - int id; + public PlayerInfoAction getAction() { + return action; + } - PlayerInfoAction(int id) { - this.id = id; - } + public UUID getUuid() { + return uuid; + } - public int getId() { - return id; - } - } + public PlayerInfoData getData() { + return data; + } - private PlayerInfoAction action; - private UUID uuid; - private PlayerInfoData data; + @Override + public byte[] serializePacket() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - public PacketPlayOutPlayerInfo(PlayerInfoAction action, UUID uuid, PlayerInfoData data) { - this.action = action; - this.uuid = uuid; - this.data = data; - } + DataOutputStream output = new DataOutputStream(buffer); + output.writeByte(Packet.getPlayOut().get(getClass())); + DataTypeIO.writeVarInt(output, action.getId()); + DataTypeIO.writeVarInt(output, 1); + DataTypeIO.writeUUID(output, uuid); - public PlayerInfoAction getAction() { - return action; - } + switch (action) { + case ADD_PLAYER: + PlayerInfoDataAddPlayer data = (PlayerInfoDataAddPlayer) this.data; + DataTypeIO.writeString(output, data.getName(), StandardCharsets.UTF_8); + if (data.getProperty().isPresent()) { + DataTypeIO.writeVarInt(output, 1); + DataTypeIO.writeString(output, "textures", StandardCharsets.UTF_8); + DataTypeIO.writeString(output, data.getProperty().get().getSkin(), StandardCharsets.UTF_8); + output.writeBoolean(true); + DataTypeIO.writeString(output, data.getProperty().get().getSignature(), StandardCharsets.UTF_8); + } else { + DataTypeIO.writeVarInt(output, 0); + } + DataTypeIO.writeVarInt(output, data.getGamemode().getId()); + DataTypeIO.writeVarInt(output, data.getPing()); + if (data.getDisplayNameJson().isPresent()) { + output.writeBoolean(true); + DataTypeIO.writeString(output, data.getDisplayNameJson().get(), StandardCharsets.UTF_8); + } else { + output.writeBoolean(false); + } + break; + case REMOVE_PLAYER: + break; + case UPDATE_DISPLAY_NAME: + break; + case UPDATE_GAMEMODE: + break; + case UPDATE_LATENCY: + break; + } - public UUID getUuid() { - return uuid; - } + return buffer.toByteArray(); + } - public PlayerInfoData getData() { - return data; - } - - @Override - public byte[] serializePacket() throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - output.writeByte(Packet.getPlayOut().get(getClass())); - DataTypeIO.writeVarInt(output, action.getId()); - DataTypeIO.writeVarInt(output, 1); - DataTypeIO.writeUUID(output, uuid); - - switch (action) { - case ADD_PLAYER: - PlayerInfoDataAddPlayer data = (PlayerInfoDataAddPlayer) this.data; - DataTypeIO.writeString(output, data.getName(), StandardCharsets.UTF_8); - if (data.getProperty().isPresent()) { - DataTypeIO.writeVarInt(output, 1); - DataTypeIO.writeString(output, "textures", StandardCharsets.UTF_8); - DataTypeIO.writeString(output, data.getProperty().get().getSkin(), StandardCharsets.UTF_8); - output.writeBoolean(true); - DataTypeIO.writeString(output, data.getProperty().get().getSignature(), StandardCharsets.UTF_8); - } else { - DataTypeIO.writeVarInt(output, 0); - } - DataTypeIO.writeVarInt(output, data.getGamemode().getId()); - DataTypeIO.writeVarInt(output, data.getPing()); - if (data.getDisplayNameJson().isPresent()) { - output.writeBoolean(true); - DataTypeIO.writeString(output, data.getDisplayNameJson().get(), StandardCharsets.UTF_8); - } else { - output.writeBoolean(false); - } - break; - case REMOVE_PLAYER: - break; - case UPDATE_DISPLAY_NAME: - break; - case UPDATE_GAMEMODE: - break; - case UPDATE_LATENCY: - break; - } - - return buffer.toByteArray(); - } + public enum PlayerInfoAction { + ADD_PLAYER(0), UPDATE_GAMEMODE(1), UPDATE_LATENCY(2), UPDATE_DISPLAY_NAME(3), REMOVE_PLAYER(4); - // ========= + int id; - public static class PlayerInfoData { + PlayerInfoAction(int id) { + this.id = id; + } - public static class PlayerInfoDataAddPlayer extends PlayerInfoData { + public int getId() { + return id; + } + } - private String name; - private Optional skin; - private GameMode gamemode; - private int ping; - private boolean hasDisplayName; - private Optional displayNameJson; - - public PlayerInfoDataAddPlayer(String name, Optional skin, GameMode gamemode, int ping, - boolean hasDisplayName, Optional displayNameJson) { - this.name = name; - this.skin = skin; - this.gamemode = gamemode; - this.ping = ping; - this.hasDisplayName = hasDisplayName; - this.displayNameJson = displayNameJson; - } + // ========= - public String getName() { - return name; - } + public static class PlayerInfoData { - public Optional getProperty() { - return skin; - } + public static class PlayerInfoDataAddPlayer extends PlayerInfoData { - public GameMode getGamemode() { - return gamemode; - } + private final String name; + private final Optional skin; + private final GameMode gamemode; + private final int ping; + private final boolean hasDisplayName; + private final Optional displayNameJson; - public int getPing() { - return ping; - } + public PlayerInfoDataAddPlayer(String name, Optional skin, GameMode gamemode, int ping, + boolean hasDisplayName, Optional displayNameJson) { + this.name = name; + this.skin = skin; + this.gamemode = gamemode; + this.ping = ping; + this.hasDisplayName = hasDisplayName; + this.displayNameJson = displayNameJson; + } - public boolean isHasDisplayName() { - return hasDisplayName; - } + public String getName() { + return name; + } - public Optional getDisplayNameJson() { - return displayNameJson; - } + public Optional getProperty() { + return skin; + } - public static class PlayerSkinProperty { + public GameMode getGamemode() { + return gamemode; + } - private String skin; - private String signature; - - public PlayerSkinProperty(String skin, String signature) { - this.skin = skin; - this.signature = signature; - } - - public String getSkin() { - return skin; - } + public int getPing() { + return ping; + } - public String getSignature() { - return signature; - } + public boolean isHasDisplayName() { + return hasDisplayName; + } - } + public Optional getDisplayNameJson() { + return displayNameJson; + } - } + public static class PlayerSkinProperty { - } + private final String skin; + private final String signature; + + public PlayerSkinProperty(String skin, String signature) { + this.skin = skin; + this.signature = signature; + } + + public String getSkin() { + return skin; + } + + public String getSignature() { + return signature; + } + + } + + } + + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutPluginMessaging.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutPluginMessaging.java index b35ee6f..03fb2b9 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutPluginMessaging.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutPluginMessaging.java @@ -1,41 +1,41 @@ package com.loohp.limbo.server.packets; +import com.loohp.limbo.utils.DataTypeIO; +import com.loohp.limbo.utils.NamespacedKey; + import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; -import com.loohp.limbo.utils.DataTypeIO; -import com.loohp.limbo.utils.NamespacedKey; - public class PacketPlayOutPluginMessaging extends PacketOut { - private NamespacedKey channel; - private byte[] data; + private final NamespacedKey channel; + private final byte[] data; - public PacketPlayOutPluginMessaging(NamespacedKey channel, byte[] data) { - this.channel = channel; - this.data = data; - } + public PacketPlayOutPluginMessaging(NamespacedKey channel, byte[] data) { + this.channel = channel; + this.data = data; + } - public NamespacedKey getChannel() { - return channel; - } + public NamespacedKey getChannel() { + return channel; + } - public byte[] getData() { - return data; - } + public byte[] getData() { + return data; + } - @Override - public byte[] serializePacket() throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - output.writeByte(Packet.getPlayOut().get(getClass())); - DataTypeIO.writeString(output, channel.toString(), StandardCharsets.UTF_8); - output.write(data); - - return buffer.toByteArray(); - } + @Override + public byte[] serializePacket() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + DataOutputStream output = new DataOutputStream(buffer); + output.writeByte(Packet.getPlayOut().get(getClass())); + DataTypeIO.writeString(output, channel.toString(), StandardCharsets.UTF_8); + output.write(data); + + return buffer.toByteArray(); + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutPositionAndLook.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutPositionAndLook.java index a400506..75c8c72 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutPositionAndLook.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutPositionAndLook.java @@ -1,5 +1,7 @@ package com.loohp.limbo.server.packets; +import com.loohp.limbo.utils.DataTypeIO; + import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; @@ -7,95 +9,92 @@ import java.util.Arrays; import java.util.Set; import java.util.stream.Collectors; -import com.loohp.limbo.utils.DataTypeIO; - public class PacketPlayOutPositionAndLook extends PacketOut { - - public enum PlayerTeleportFlags { - X((byte) 0x01), - Y((byte) 0x02), - Z((byte) 0x04), - Y_ROT((byte) 0x08), - X_ROT((byte) 0x10); - - byte bit; - - PlayerTeleportFlags(byte bit) { - this.bit = bit; - } - - public byte getBit() { - return bit; - } - } - - private double x; - private double y; - private double z; - private float yaw; - private float pitch; - private Set flags; - private int teleportId; - - public PacketPlayOutPositionAndLook(double x, double y, double z, float yaw, float pitch, int teleportId, PlayerTeleportFlags... flags) { - this.x = x; - this.y = y; - this.z = z; - this.yaw = yaw; - this.pitch = pitch; - this.teleportId = teleportId; - this.flags = Arrays.asList(flags).stream().collect(Collectors.toSet()); - } - public double getX() { - return x; - } + private final double x; + private final double y; + private final double z; + private final float yaw; + private final float pitch; + private final Set flags; + private final int teleportId; + public PacketPlayOutPositionAndLook(double x, double y, double z, float yaw, float pitch, int teleportId, PlayerTeleportFlags... flags) { + this.x = x; + this.y = y; + this.z = z; + this.yaw = yaw; + this.pitch = pitch; + this.teleportId = teleportId; + this.flags = Arrays.asList(flags).stream().collect(Collectors.toSet()); + } - public double getY() { - return y; - } + public double getX() { + return x; + } - public double getZ() { - return z; - } + public double getY() { + return y; + } - public float getYaw() { - return yaw; - } + public double getZ() { + return z; + } - public float getPitch() { - return pitch; - } + public float getYaw() { + return yaw; + } - public Set getFlags() { - return flags; - } + public float getPitch() { + return pitch; + } - public int getTeleportId() { - return teleportId; - } - - @Override - public byte[] serializePacket() throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - output.writeByte(Packet.getPlayOut().get(getClass())); - output.writeDouble(x); - output.writeDouble(y); - output.writeDouble(z); - output.writeFloat(yaw); - output.writeFloat(pitch); - - byte flag = 0; - for (PlayerTeleportFlags each : flags) { - flag = (byte) (flag | each.getBit()); - } - - output.writeByte(flag); - DataTypeIO.writeVarInt(output, teleportId); - - return buffer.toByteArray(); - } + public Set getFlags() { + return flags; + } + + public int getTeleportId() { + return teleportId; + } + + @Override + public byte[] serializePacket() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + DataOutputStream output = new DataOutputStream(buffer); + output.writeByte(Packet.getPlayOut().get(getClass())); + output.writeDouble(x); + output.writeDouble(y); + output.writeDouble(z); + output.writeFloat(yaw); + output.writeFloat(pitch); + + byte flag = 0; + for (PlayerTeleportFlags each : flags) { + flag = (byte) (flag | each.getBit()); + } + + output.writeByte(flag); + DataTypeIO.writeVarInt(output, teleportId); + + return buffer.toByteArray(); + } + + public enum PlayerTeleportFlags { + X((byte) 0x01), + Y((byte) 0x02), + Z((byte) 0x04), + Y_ROT((byte) 0x08), + X_ROT((byte) 0x10); + + byte bit; + + PlayerTeleportFlags(byte bit) { + this.bit = bit; + } + + public byte getBit() { + return bit; + } + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutRespawn.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutRespawn.java index 2cbf57f..bc87545 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutRespawn.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutRespawn.java @@ -1,97 +1,96 @@ package com.loohp.limbo.server.packets; -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; - import com.loohp.limbo.utils.DataTypeIO; import com.loohp.limbo.utils.GameMode; import com.loohp.limbo.utils.NamespacedKey; import com.loohp.limbo.world.Environment; import com.loohp.limbo.world.World; - import net.querz.nbt.tag.CompoundTag; import net.querz.nbt.tag.ListTag; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + public class PacketPlayOutRespawn extends PacketOut { - private Environment dimension; - private String worldName; - private CompoundTag dimensionCodec; - private long hashedSeed; - private GameMode gamemode; - private boolean isDebug; - private boolean isFlat; - private boolean copyMetaData; + private final Environment dimension; + private final String worldName; + private final CompoundTag dimensionCodec; + private final long hashedSeed; + private final GameMode gamemode; + private final boolean isDebug; + private final boolean isFlat; + private final boolean copyMetaData; - public PacketPlayOutRespawn(World world, CompoundTag dimensionCodec, long hashedSeed, GameMode gamemode, boolean isDebug, boolean isFlat, boolean copyMetaData) { - this.dimension = world.getEnvironment(); - this.dimensionCodec = dimensionCodec; - this.worldName = new NamespacedKey(world.getName()).toString(); - this.hashedSeed = hashedSeed; - this.gamemode = gamemode; - this.isDebug = isDebug; - this.isFlat = isFlat; - this.copyMetaData = copyMetaData; - } + public PacketPlayOutRespawn(World world, CompoundTag dimensionCodec, long hashedSeed, GameMode gamemode, boolean isDebug, boolean isFlat, boolean copyMetaData) { + this.dimension = world.getEnvironment(); + this.dimensionCodec = dimensionCodec; + this.worldName = new NamespacedKey(world.getName()).toString(); + this.hashedSeed = hashedSeed; + this.gamemode = gamemode; + this.isDebug = isDebug; + this.isFlat = isFlat; + this.copyMetaData = copyMetaData; + } - public CompoundTag getDimensionCodec() { - return dimensionCodec; - } + public CompoundTag getDimensionCodec() { + return dimensionCodec; + } - public Environment getDimension() { - return dimension; - } + public Environment getDimension() { + return dimension; + } - public String getWorldName() { - return worldName; - } + public String getWorldName() { + return worldName; + } - public long getHashedSeed() { - return hashedSeed; - } + public long getHashedSeed() { + return hashedSeed; + } - public GameMode getGamemode() { - return gamemode; - } + public GameMode getGamemode() { + return gamemode; + } - public boolean isDebug() { - return isDebug; - } + public boolean isDebug() { + return isDebug; + } - public boolean isFlat() { - return isFlat; - } + public boolean isFlat() { + return isFlat; + } - public boolean isCopyMetaData() { - return copyMetaData; - } + public boolean isCopyMetaData() { + return copyMetaData; + } - @Override - public byte[] serializePacket() throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - output.writeByte(Packet.getPlayOut().get(getClass())); - CompoundTag tag = null; - ListTag list = dimensionCodec.getCompoundTag("minecraft:dimension_type").getListTag("value").asCompoundTagList(); - for (CompoundTag each : list) { - if (each.getString("name").equals(dimension.getNamespacedKey().toString())) { - tag = each.getCompoundTag("element"); - break; - } - } - DataTypeIO.writeCompoundTag(output, tag != null ? tag : list.get(0)); - DataTypeIO.writeString(output, worldName, StandardCharsets.UTF_8); - output.writeLong(hashedSeed); + @Override + public byte[] serializePacket() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + DataOutputStream output = new DataOutputStream(buffer); + output.writeByte(Packet.getPlayOut().get(getClass())); + CompoundTag tag = null; + ListTag list = dimensionCodec.getCompoundTag("minecraft:dimension_type").getListTag("value").asCompoundTagList(); + for (CompoundTag each : list) { + if (each.getString("name").equals(dimension.getNamespacedKey().toString())) { + tag = each.getCompoundTag("element"); + break; + } + } + DataTypeIO.writeCompoundTag(output, tag != null ? tag : list.get(0)); + DataTypeIO.writeString(output, worldName, StandardCharsets.UTF_8); + output.writeLong(hashedSeed); output.writeByte((byte) gamemode.getId()); - output.writeByte((byte) gamemode.getId()); - output.writeBoolean(isDebug); - output.writeBoolean(isFlat); - output.writeBoolean(copyMetaData); - - return buffer.toByteArray(); - } + output.writeByte((byte) gamemode.getId()); + output.writeBoolean(isDebug); + output.writeBoolean(isFlat); + output.writeBoolean(copyMetaData); + + return buffer.toByteArray(); + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutSpawnEntity.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutSpawnEntity.java index 209f848..817ba58 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutSpawnEntity.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutSpawnEntity.java @@ -1,111 +1,111 @@ package com.loohp.limbo.server.packets; +import com.loohp.limbo.entity.EntityType; +import com.loohp.limbo.utils.DataTypeIO; + import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.UUID; -import com.loohp.limbo.entity.EntityType; -import com.loohp.limbo.utils.DataTypeIO; - public class PacketPlayOutSpawnEntity extends PacketOut { - - private int entityId; - private UUID uuid; - private EntityType type; - private double x; - private double y; - private double z; - private float pitch; - private float yaw; - private int data; - private short velocityX; - private short velocityY; - private short velocityZ; - - public PacketPlayOutSpawnEntity(int entityId, UUID uuid, EntityType type, double x, double y, double z, float pitch, float yaw, short velocityX, short velocityY, short velocityZ) { - this.entityId = entityId; - this.uuid = uuid; - this.type = type; - this.x = x; - this.y = y; - this.z = z; - this.pitch = pitch; - this.yaw = yaw; - this.data = 0; //TO-DO - this.velocityX = velocityX; - this.velocityY = velocityY; - this.velocityZ = velocityZ; - } - public int getEntityId() { - return entityId; - } + private final int entityId; + private final UUID uuid; + private final EntityType type; + private final double x; + private final double y; + private final double z; + private final float pitch; + private final float yaw; + private final int data; + private final short velocityX; + private final short velocityY; + private final short velocityZ; - public UUID getUuid() { - return uuid; - } + public PacketPlayOutSpawnEntity(int entityId, UUID uuid, EntityType type, double x, double y, double z, float pitch, float yaw, short velocityX, short velocityY, short velocityZ) { + this.entityId = entityId; + this.uuid = uuid; + this.type = type; + this.x = x; + this.y = y; + this.z = z; + this.pitch = pitch; + this.yaw = yaw; + this.data = 0; //TO-DO + this.velocityX = velocityX; + this.velocityY = velocityY; + this.velocityZ = velocityZ; + } - public EntityType getType() { - return type; - } + public int getEntityId() { + return entityId; + } - public double getX() { - return x; - } + public UUID getUuid() { + return uuid; + } - public double getY() { - return y; - } + public EntityType getType() { + return type; + } - public double getZ() { - return z; - } + public double getX() { + return x; + } - public float getPitch() { - return pitch; - } + public double getY() { + return y; + } - public float getYaw() { - return yaw; - } + public double getZ() { + return z; + } - public int getData() { - return data; - } + public float getPitch() { + return pitch; + } - public short getVelocityX() { - return velocityX; - } + public float getYaw() { + return yaw; + } - public short getVelocityY() { - return velocityY; - } + public int getData() { + return data; + } - public short getVelocityZ() { - return velocityZ; - } + public short getVelocityX() { + return velocityX; + } - @Override - public byte[] serializePacket() throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - output.writeByte(Packet.getPlayOut().get(getClass())); - DataTypeIO.writeVarInt(output, entityId); - DataTypeIO.writeUUID(output, uuid); - DataTypeIO.writeVarInt(output, type.getTypeId()); - output.writeDouble(x); - output.writeDouble(y); - output.writeDouble(z); - output.writeByte((byte) (int) (pitch * 256.0F / 360.0F)); - output.writeByte((byte) (int) (yaw * 256.0F / 360.0F)); - output.writeInt(data); - output.writeShort((int) (velocityX * 8000)); - output.writeShort((int) (velocityY * 8000)); - output.writeShort((int) (velocityZ * 8000)); - - return buffer.toByteArray(); - } + public short getVelocityY() { + return velocityY; + } + + public short getVelocityZ() { + return velocityZ; + } + + @Override + public byte[] serializePacket() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + DataOutputStream output = new DataOutputStream(buffer); + output.writeByte(Packet.getPlayOut().get(getClass())); + DataTypeIO.writeVarInt(output, entityId); + DataTypeIO.writeUUID(output, uuid); + DataTypeIO.writeVarInt(output, type.getTypeId()); + output.writeDouble(x); + output.writeDouble(y); + output.writeDouble(z); + output.writeByte((byte) (int) (pitch * 256.0F / 360.0F)); + output.writeByte((byte) (int) (yaw * 256.0F / 360.0F)); + output.writeInt(data); + output.writeShort(velocityX * 8000); + output.writeShort(velocityY * 8000); + output.writeShort(velocityZ * 8000); + + return buffer.toByteArray(); + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutSpawnEntityLiving.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutSpawnEntityLiving.java index 687c7bd..5aecd5b 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutSpawnEntityLiving.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutSpawnEntityLiving.java @@ -1,111 +1,111 @@ package com.loohp.limbo.server.packets; +import com.loohp.limbo.entity.EntityType; +import com.loohp.limbo.utils.DataTypeIO; + import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.UUID; -import com.loohp.limbo.entity.EntityType; -import com.loohp.limbo.utils.DataTypeIO; - public class PacketPlayOutSpawnEntityLiving extends PacketOut { - - private int entityId; - private UUID uuid; - private EntityType type; - private double x; - private double y; - private double z; - private float yaw; - private float pitch; - private float headPitch; - private short velocityX; - private short velocityY; - private short velocityZ; - - public PacketPlayOutSpawnEntityLiving(int entityId, UUID uuid, EntityType type, double x, double y, double z, float yaw, float pitch, float headPitch, short velocityX, short velocityY, short velocityZ) { - this.entityId = entityId; - this.uuid = uuid; - this.type = type; - this.x = x; - this.y = y; - this.z = z; - this.yaw = yaw; - this.pitch = pitch; - this.headPitch = headPitch; - this.velocityX = velocityX; - this.velocityY = velocityY; - this.velocityZ = velocityZ; - } - public int getEntityId() { - return entityId; - } + private final int entityId; + private final UUID uuid; + private final EntityType type; + private final double x; + private final double y; + private final double z; + private final float yaw; + private final float pitch; + private final float headPitch; + private final short velocityX; + private final short velocityY; + private final short velocityZ; - public UUID getUuid() { - return uuid; - } + public PacketPlayOutSpawnEntityLiving(int entityId, UUID uuid, EntityType type, double x, double y, double z, float yaw, float pitch, float headPitch, short velocityX, short velocityY, short velocityZ) { + this.entityId = entityId; + this.uuid = uuid; + this.type = type; + this.x = x; + this.y = y; + this.z = z; + this.yaw = yaw; + this.pitch = pitch; + this.headPitch = headPitch; + this.velocityX = velocityX; + this.velocityY = velocityY; + this.velocityZ = velocityZ; + } - public EntityType getType() { - return type; - } + public int getEntityId() { + return entityId; + } - public double getX() { - return x; - } + public UUID getUuid() { + return uuid; + } - public double getY() { - return y; - } + public EntityType getType() { + return type; + } - public double getZ() { - return z; - } - - public float getYaw() { - return yaw; - } + public double getX() { + return x; + } - public float getPitch() { - return pitch; - } + public double getY() { + return y; + } - public float getHeadPitch() { - return headPitch; - } + public double getZ() { + return z; + } - public short getVelocityX() { - return velocityX; - } + public float getYaw() { + return yaw; + } - public short getVelocityY() { - return velocityY; - } + public float getPitch() { + return pitch; + } - public short getVelocityZ() { - return velocityZ; - } + public float getHeadPitch() { + return headPitch; + } - @Override - public byte[] serializePacket() throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - output.writeByte(Packet.getPlayOut().get(getClass())); - DataTypeIO.writeVarInt(output, entityId); - DataTypeIO.writeUUID(output, uuid); - DataTypeIO.writeVarInt(output, type.getTypeId()); - output.writeDouble(x); - output.writeDouble(y); - output.writeDouble(z); - output.writeByte((byte) (int) (yaw * 256.0F / 360.0F)); - output.writeByte((byte) (int) (pitch * 256.0F / 360.0F)); - output.writeByte((byte) (int) (headPitch * 256.0F / 360.0F)); - output.writeShort((int) (velocityX * 8000)); - output.writeShort((int) (velocityY * 8000)); - output.writeShort((int) (velocityZ * 8000)); - - return buffer.toByteArray(); - } + public short getVelocityX() { + return velocityX; + } + + public short getVelocityY() { + return velocityY; + } + + public short getVelocityZ() { + return velocityZ; + } + + @Override + public byte[] serializePacket() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + DataOutputStream output = new DataOutputStream(buffer); + output.writeByte(Packet.getPlayOut().get(getClass())); + DataTypeIO.writeVarInt(output, entityId); + DataTypeIO.writeUUID(output, uuid); + DataTypeIO.writeVarInt(output, type.getTypeId()); + output.writeDouble(x); + output.writeDouble(y); + output.writeDouble(z); + output.writeByte((byte) (int) (yaw * 256.0F / 360.0F)); + output.writeByte((byte) (int) (pitch * 256.0F / 360.0F)); + output.writeByte((byte) (int) (headPitch * 256.0F / 360.0F)); + output.writeShort(velocityX * 8000); + output.writeShort(velocityY * 8000); + output.writeShort(velocityZ * 8000); + + return buffer.toByteArray(); + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutSpawnPosition.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutSpawnPosition.java index a53502b..7143826 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutSpawnPosition.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutSpawnPosition.java @@ -1,32 +1,32 @@ package com.loohp.limbo.server.packets; +import com.loohp.limbo.utils.DataTypeIO; +import com.loohp.limbo.world.BlockPosition; + import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; -import com.loohp.limbo.utils.DataTypeIO; -import com.loohp.limbo.world.BlockPosition; - public class PacketPlayOutSpawnPosition extends PacketOut { - - private BlockPosition position; - - public PacketPlayOutSpawnPosition(BlockPosition position) { - this.position = position; - } - public BlockPosition getPosition() { - return position; - } - - public byte[] serializePacket() throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - output.writeByte(Packet.getPlayOut().get(getClass())); - DataTypeIO.writeBlockPosition(output, position); - - return buffer.toByteArray(); - } + private final BlockPosition position; + + public PacketPlayOutSpawnPosition(BlockPosition position) { + this.position = position; + } + + public BlockPosition getPosition() { + return position; + } + + public byte[] serializePacket() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + DataOutputStream output = new DataOutputStream(buffer); + output.writeByte(Packet.getPlayOut().get(getClass())); + DataTypeIO.writeBlockPosition(output, position); + + return buffer.toByteArray(); + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutTabComplete.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutTabComplete.java index 990f46a..69bee4d 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutTabComplete.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutTabComplete.java @@ -1,88 +1,87 @@ package com.loohp.limbo.server.packets; +import com.loohp.limbo.utils.DataTypeIO; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.chat.ComponentSerializer; + import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Optional; -import com.loohp.limbo.utils.DataTypeIO; - -import net.md_5.bungee.api.chat.BaseComponent; -import net.md_5.bungee.chat.ComponentSerializer; - public class PacketPlayOutTabComplete extends PacketOut { - private int id; - private int start; - private int length; - private TabCompleteMatches[] matches; + private final int id; + private final int start; + private final int length; + private final TabCompleteMatches[] matches; - public PacketPlayOutTabComplete(int id, int start, int length, TabCompleteMatches... matches) { - this.id = id; - this.start = start; - this.length = length; - this.matches = matches; - } + public PacketPlayOutTabComplete(int id, int start, int length, TabCompleteMatches... matches) { + this.id = id; + this.start = start; + this.length = length; + this.matches = matches; + } - public int getId() { - return id; - } + public int getId() { + return id; + } - public int getStart() { - return start; - } + public int getStart() { + return start; + } - public int getLength() { - return length; - } + public int getLength() { + return length; + } - public TabCompleteMatches[] getMatches() { - return matches; - } + public TabCompleteMatches[] getMatches() { + return matches; + } - @Override - public byte[] serializePacket() throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - output.writeByte(Packet.getPlayOut().get(getClass())); - DataTypeIO.writeVarInt(output, id); - DataTypeIO.writeVarInt(output, start); - DataTypeIO.writeVarInt(output, length); - DataTypeIO.writeVarInt(output, matches.length); - - for (TabCompleteMatches match : matches) { - DataTypeIO.writeString(output, match.getMatch(), StandardCharsets.UTF_8); - if (match.getTooltip().isPresent()) { - output.writeBoolean(true); - DataTypeIO.writeString(output, ComponentSerializer.toString(match.getTooltip().get()), StandardCharsets.UTF_8); - } else { - output.writeBoolean(false); - } - } - - return buffer.toByteArray(); - } + @Override + public byte[] serializePacket() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - public static class TabCompleteMatches { + DataOutputStream output = new DataOutputStream(buffer); + output.writeByte(Packet.getPlayOut().get(getClass())); + DataTypeIO.writeVarInt(output, id); + DataTypeIO.writeVarInt(output, start); + DataTypeIO.writeVarInt(output, length); + DataTypeIO.writeVarInt(output, matches.length); - private String match; - private Optional tooltip; + for (TabCompleteMatches match : matches) { + DataTypeIO.writeString(output, match.getMatch(), StandardCharsets.UTF_8); + if (match.getTooltip().isPresent()) { + output.writeBoolean(true); + DataTypeIO.writeString(output, ComponentSerializer.toString(match.getTooltip().get()), StandardCharsets.UTF_8); + } else { + output.writeBoolean(false); + } + } - public TabCompleteMatches(String match, BaseComponent... tooltip) { - this.match = match; - this.tooltip = tooltip.length > 0 ? Optional.of(tooltip) : Optional.empty(); - } + return buffer.toByteArray(); + } - public String getMatch() { - return match; - } + public static class TabCompleteMatches { - public Optional getTooltip() { - return tooltip; - } + private final String match; + private final Optional tooltip; - } + public TabCompleteMatches(String match, BaseComponent... tooltip) { + this.match = match; + this.tooltip = tooltip.length > 0 ? Optional.of(tooltip) : Optional.empty(); + } + + public String getMatch() { + return match; + } + + public Optional getTooltip() { + return tooltip; + } + + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutUnloadChunk.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutUnloadChunk.java index ed105ef..62cab66 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutUnloadChunk.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutUnloadChunk.java @@ -5,33 +5,33 @@ import java.io.DataOutputStream; import java.io.IOException; public class PacketPlayOutUnloadChunk extends PacketOut { - - private int chunkX; - private int chunkZ; - - public PacketPlayOutUnloadChunk(int chunkX, int chunkZ) { - this.chunkX = chunkX; - this.chunkZ = chunkZ; - } - public int getChunkX() { - return chunkX; - } + private final int chunkX; + private final int chunkZ; - public int getChunkZ() { - return chunkZ; - } - - @Override - public byte[] serializePacket() throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - output.writeByte(Packet.getPlayOut().get(getClass())); - output.writeInt(chunkX); - output.writeInt(chunkZ); - - return buffer.toByteArray(); - } + public PacketPlayOutUnloadChunk(int chunkX, int chunkZ) { + this.chunkX = chunkX; + this.chunkZ = chunkZ; + } + + public int getChunkX() { + return chunkX; + } + + public int getChunkZ() { + return chunkZ; + } + + @Override + public byte[] serializePacket() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + DataOutputStream output = new DataOutputStream(buffer); + output.writeByte(Packet.getPlayOut().get(getClass())); + output.writeInt(chunkX); + output.writeInt(chunkZ); + + return buffer.toByteArray(); + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutUpdateViewPosition.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutUpdateViewPosition.java index 8652c09..b5dd8ed 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutUpdateViewPosition.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutUpdateViewPosition.java @@ -1,39 +1,39 @@ package com.loohp.limbo.server.packets; +import com.loohp.limbo.utils.DataTypeIO; + import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; -import com.loohp.limbo.utils.DataTypeIO; - public class PacketPlayOutUpdateViewPosition extends PacketOut { - - private int chunkX; - private int chunkZ; - - public PacketPlayOutUpdateViewPosition(int chunkX, int chunkZ) { - this.chunkX = chunkX; - this.chunkZ = chunkZ; - } - public int getChunkX() { - return chunkX; - } + private final int chunkX; + private final int chunkZ; - public int getChunkZ() { - return chunkZ; - } - - @Override - public byte[] serializePacket() throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - output.writeByte(Packet.getPlayOut().get(getClass())); - DataTypeIO.writeVarInt(output, chunkX); - DataTypeIO.writeVarInt(output, chunkZ); - - return buffer.toByteArray(); - } + public PacketPlayOutUpdateViewPosition(int chunkX, int chunkZ) { + this.chunkX = chunkX; + this.chunkZ = chunkZ; + } + + public int getChunkX() { + return chunkX; + } + + public int getChunkZ() { + return chunkZ; + } + + @Override + public byte[] serializePacket() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + DataOutputStream output = new DataOutputStream(buffer); + output.writeByte(Packet.getPlayOut().get(getClass())); + DataTypeIO.writeVarInt(output, chunkX); + DataTypeIO.writeVarInt(output, chunkZ); + + return buffer.toByteArray(); + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketStatusInPing.java b/src/main/java/com/loohp/limbo/server/packets/PacketStatusInPing.java index df53ebd..5202f86 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketStatusInPing.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketStatusInPing.java @@ -4,19 +4,19 @@ import java.io.DataInputStream; import java.io.IOException; public class PacketStatusInPing extends PacketIn { - - private long payload; - - public PacketStatusInPing(long payload) { - this.payload = payload; - } - - public PacketStatusInPing(DataInputStream in) throws IOException { - this(in.readLong()); - } - public long getPayload() { - return payload; - } - + private final long payload; + + public PacketStatusInPing(long payload) { + this.payload = payload; + } + + public PacketStatusInPing(DataInputStream in) throws IOException { + this(in.readLong()); + } + + public long getPayload() { + return payload; + } + } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketStatusInRequest.java b/src/main/java/com/loohp/limbo/server/packets/PacketStatusInRequest.java index 2d195f8..0640be3 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketStatusInRequest.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketStatusInRequest.java @@ -3,13 +3,13 @@ package com.loohp.limbo.server.packets; import java.io.DataInputStream; public class PacketStatusInRequest extends PacketIn { - - public PacketStatusInRequest() { - - } - - public PacketStatusInRequest(DataInputStream in) { - this(); - } + + public PacketStatusInRequest() { + + } + + public PacketStatusInRequest(DataInputStream in) { + this(); + } } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketStatusOutPong.java b/src/main/java/com/loohp/limbo/server/packets/PacketStatusOutPong.java index ebf85d8..4f61d24 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketStatusOutPong.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketStatusOutPong.java @@ -5,26 +5,26 @@ import java.io.DataOutputStream; import java.io.IOException; public class PacketStatusOutPong extends PacketOut { - - private long payload; - - public PacketStatusOutPong(long payload) { - this.payload = payload; - } - public long getPayload() { - return payload; - } - - @Override - public byte[] serializePacket() throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - output.writeByte(Packet.getStatusOut().get(getClass())); - output.writeLong(payload); - - return buffer.toByteArray(); - } - + private final long payload; + + public PacketStatusOutPong(long payload) { + this.payload = payload; + } + + public long getPayload() { + return payload; + } + + @Override + public byte[] serializePacket() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + DataOutputStream output = new DataOutputStream(buffer); + output.writeByte(Packet.getStatusOut().get(getClass())); + output.writeLong(payload); + + return buffer.toByteArray(); + } + } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketStatusOutResponse.java b/src/main/java/com/loohp/limbo/server/packets/PacketStatusOutResponse.java index 695c333..d7a653b 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketStatusOutResponse.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketStatusOutResponse.java @@ -1,33 +1,33 @@ package com.loohp.limbo.server.packets; +import com.loohp.limbo.utils.DataTypeIO; + import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; -import com.loohp.limbo.utils.DataTypeIO; - public class PacketStatusOutResponse extends PacketOut { - - private String json; - - public PacketStatusOutResponse(String json) { - this.json = json; - } - - public String getJson() { - return json; - } - - @Override - public byte[] serializePacket() throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - output.writeByte(Packet.getStatusOut().get(getClass())); - DataTypeIO.writeString(output, json, StandardCharsets.UTF_8); - - return buffer.toByteArray(); - } + + private final String json; + + public PacketStatusOutResponse(String json) { + this.json = json; + } + + public String getJson() { + return json; + } + + @Override + public byte[] serializePacket() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + DataOutputStream output = new DataOutputStream(buffer); + output.writeByte(Packet.getStatusOut().get(getClass())); + DataTypeIO.writeString(output, json, StandardCharsets.UTF_8); + + return buffer.toByteArray(); + } } diff --git a/src/main/java/com/loohp/limbo/utils/BitsUtils.java b/src/main/java/com/loohp/limbo/utils/BitsUtils.java index e5394cc..1b4d5dc 100644 --- a/src/main/java/com/loohp/limbo/utils/BitsUtils.java +++ b/src/main/java/com/loohp/limbo/utils/BitsUtils.java @@ -7,23 +7,23 @@ import java.util.List; public class BitsUtils { - public static BitSet shiftAfter(BitSet bitset, int from, int shift) { - BitSet subset = bitset.get(from, bitset.length()); - for (int i = 0; i < subset.length(); i++) { - bitset.set(from + shift + i, subset.get(i)); - } - if (shift > 0) { - for (int i = 0; i < shift; i++) { - bitset.set(from + i, false); - } - } - return bitset; - } - - public static String toLongString(BitSet bitset) { + public static BitSet shiftAfter(BitSet bitset, int from, int shift) { + BitSet subset = bitset.get(from, bitset.length()); + for (int i = 0; i < subset.length(); i++) { + bitset.set(from + shift + i, subset.get(i)); + } + if (shift > 0) { + for (int i = 0; i < shift; i++) { + bitset.set(from + i, false); + } + } + return bitset; + } + + public static String toLongString(BitSet bitset) { List list = new ArrayList<>(); for (long l : bitset.toLongArray()) { - list.add(Long.toBinaryString(l)); + list.add(Long.toBinaryString(l)); } return Arrays.toString(list.toArray()); } diff --git a/src/main/java/com/loohp/limbo/utils/BungeeLoginMessageUtils.java b/src/main/java/com/loohp/limbo/utils/BungeeLoginMessageUtils.java index 97d66bc..3882bad 100644 --- a/src/main/java/com/loohp/limbo/utils/BungeeLoginMessageUtils.java +++ b/src/main/java/com/loohp/limbo/utils/BungeeLoginMessageUtils.java @@ -1,58 +1,58 @@ package com.loohp.limbo.utils; +import com.google.common.io.ByteArrayDataInput; +import com.google.common.io.ByteArrayDataOutput; +import com.google.common.io.ByteStreams; +import com.loohp.limbo.server.packets.PacketPlayOutPluginMessaging; + import java.io.DataOutputStream; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.UUID; -import com.google.common.io.ByteArrayDataInput; -import com.google.common.io.ByteArrayDataOutput; -import com.google.common.io.ByteStreams; -import com.loohp.limbo.server.packets.PacketPlayOutPluginMessaging; - public class BungeeLoginMessageUtils { - public static void sendUUIDRequest(DataOutputStream output) throws IOException { - ByteArrayDataOutput out = ByteStreams.newDataOutput(); - out.writeUTF("UUID"); - - PacketPlayOutPluginMessaging packet = new PacketPlayOutPluginMessaging(new NamespacedKey("bungeecord", "main"), out.toByteArray()); - byte[] packetByte = packet.serializePacket(); - DataTypeIO.writeVarInt(output, packetByte.length); - output.write(packetByte); - } - - public static UUID readUUIDResponse(byte[] data) { - ByteArrayDataInput in = ByteStreams.newDataInput(data); - String subchannel = in.readUTF(); - if (subchannel.equals("UUID")) { - return UUID.fromString(in.readUTF()); - } else { - throw new RuntimeException("Bungeecord Message receieved is not an IP"); - } - } - - public static void sendIPRequest(DataOutputStream output) throws IOException { - ByteArrayDataOutput out = ByteStreams.newDataOutput(); - out.writeUTF("IP"); - - PacketPlayOutPluginMessaging packet = new PacketPlayOutPluginMessaging(new NamespacedKey("bungeecord", "main"), out.toByteArray()); - byte[] packetByte = packet.serializePacket(); - DataTypeIO.writeVarInt(output, packetByte.length); - output.write(packetByte); - } - - public static InetAddress readIPResponse(byte[] data) throws UnknownHostException { - ByteArrayDataInput in = ByteStreams.newDataInput(data); - String subchannel = in.readUTF(); - if (subchannel.equals("IP")) { - String ip = in.readUTF(); - in.readInt(); - return InetAddress.getByName(ip); - } else { - throw new RuntimeException("Bungeecord Message receieved is not an IP"); - } - } + public static void sendUUIDRequest(DataOutputStream output) throws IOException { + ByteArrayDataOutput out = ByteStreams.newDataOutput(); + out.writeUTF("UUID"); + + PacketPlayOutPluginMessaging packet = new PacketPlayOutPluginMessaging(new NamespacedKey("bungeecord", "main"), out.toByteArray()); + byte[] packetByte = packet.serializePacket(); + DataTypeIO.writeVarInt(output, packetByte.length); + output.write(packetByte); + } + + public static UUID readUUIDResponse(byte[] data) { + ByteArrayDataInput in = ByteStreams.newDataInput(data); + String subchannel = in.readUTF(); + if (subchannel.equals("UUID")) { + return UUID.fromString(in.readUTF()); + } else { + throw new RuntimeException("Bungeecord Message receieved is not an IP"); + } + } + + public static void sendIPRequest(DataOutputStream output) throws IOException { + ByteArrayDataOutput out = ByteStreams.newDataOutput(); + out.writeUTF("IP"); + + PacketPlayOutPluginMessaging packet = new PacketPlayOutPluginMessaging(new NamespacedKey("bungeecord", "main"), out.toByteArray()); + byte[] packetByte = packet.serializePacket(); + DataTypeIO.writeVarInt(output, packetByte.length); + output.write(packetByte); + } + + public static InetAddress readIPResponse(byte[] data) throws UnknownHostException { + ByteArrayDataInput in = ByteStreams.newDataInput(data); + String subchannel = in.readUTF(); + if (subchannel.equals("IP")) { + String ip = in.readUTF(); + in.readInt(); + return InetAddress.getByName(ip); + } else { + throw new RuntimeException("Bungeecord Message receieved is not an IP"); + } + } } diff --git a/src/main/java/com/loohp/limbo/utils/ChunkDataUtils.java b/src/main/java/com/loohp/limbo/utils/ChunkDataUtils.java index 18d98e6..2efd04f 100644 --- a/src/main/java/com/loohp/limbo/utils/ChunkDataUtils.java +++ b/src/main/java/com/loohp/limbo/utils/ChunkDataUtils.java @@ -3,24 +3,24 @@ package com.loohp.limbo.utils; import net.querz.mca.Section; public class ChunkDataUtils { - - public static void adjustBlockStateBits(int newBits, Section section, int dataVersion) { - //increases or decreases the amount of bits used per BlockState - //based on the size of the palette. - long[] blockStates = section.getBlockStates(); - long[] newBlockStates; + public static void adjustBlockStateBits(int newBits, Section section, int dataVersion) { + //increases or decreases the amount of bits used per BlockState + //based on the size of the palette. - if (dataVersion < 2527) { - newBlockStates = newBits == blockStates.length / 64 ? blockStates : new long[newBits * 64]; - } else { - int newLength = (int) Math.ceil(4096D / (64D / newBits)); - newBlockStates = newBits == blockStates.length / 64 ? blockStates : new long[newLength]; - } - for (int i = 0; i < 4096; i++) { - section.setPaletteIndex(i, section.getPaletteIndex(i), newBlockStates); - } - section.setBlockStates(newBlockStates); - } + long[] blockStates = section.getBlockStates(); + long[] newBlockStates; + + if (dataVersion < 2527) { + newBlockStates = newBits == blockStates.length / 64 ? blockStates : new long[newBits * 64]; + } else { + int newLength = (int) Math.ceil(4096D / (64D / newBits)); + newBlockStates = newBits == blockStates.length / 64 ? blockStates : new long[newLength]; + } + for (int i = 0; i < 4096; i++) { + section.setPaletteIndex(i, section.getPaletteIndex(i), newBlockStates); + } + section.setBlockStates(newBlockStates); + } } diff --git a/src/main/java/com/loohp/limbo/utils/CustomArrayUtils.java b/src/main/java/com/loohp/limbo/utils/CustomArrayUtils.java index 3a10165..6285edf 100644 --- a/src/main/java/com/loohp/limbo/utils/CustomArrayUtils.java +++ b/src/main/java/com/loohp/limbo/utils/CustomArrayUtils.java @@ -1,21 +1,21 @@ package com.loohp.limbo.utils; public class CustomArrayUtils { - - public static int[] longArrayToIntArray(long[] numbers) { - int[] intNumbers = new int[numbers.length]; - for(int i = 0; i < numbers.length; i++) { - intNumbers[i] = (int) numbers[i]; - } - return intNumbers; - } - - public static byte[] longArrayToByteArray(long[] numbers) { - byte[] intNumbers = new byte[numbers.length]; - for(int i = 0; i < numbers.length; i++) { - intNumbers[i] = (byte) numbers[i]; - } - return intNumbers; - } + + public static int[] longArrayToIntArray(long[] numbers) { + int[] intNumbers = new int[numbers.length]; + for (int i = 0; i < numbers.length; i++) { + intNumbers[i] = (int) numbers[i]; + } + return intNumbers; + } + + public static byte[] longArrayToByteArray(long[] numbers) { + byte[] intNumbers = new byte[numbers.length]; + for (int i = 0; i < numbers.length; i++) { + intNumbers[i] = (byte) numbers[i]; + } + return intNumbers; + } } diff --git a/src/main/java/com/loohp/limbo/utils/CustomNBTUtils.java b/src/main/java/com/loohp/limbo/utils/CustomNBTUtils.java index 2928cd9..f7bb8c6 100644 --- a/src/main/java/com/loohp/limbo/utils/CustomNBTUtils.java +++ b/src/main/java/com/loohp/limbo/utils/CustomNBTUtils.java @@ -1,180 +1,167 @@ package com.loohp.limbo.utils; +import net.querz.nbt.tag.*; import org.json.simple.JSONArray; import org.json.simple.JSONObject; -import net.querz.nbt.tag.ByteArrayTag; -import net.querz.nbt.tag.ByteTag; -import net.querz.nbt.tag.CompoundTag; -import net.querz.nbt.tag.DoubleTag; -import net.querz.nbt.tag.FloatTag; -import net.querz.nbt.tag.IntArrayTag; -import net.querz.nbt.tag.IntTag; -import net.querz.nbt.tag.ListTag; -import net.querz.nbt.tag.LongArrayTag; -import net.querz.nbt.tag.LongTag; -import net.querz.nbt.tag.ShortTag; -import net.querz.nbt.tag.StringTag; -import net.querz.nbt.tag.Tag; - @SuppressWarnings("rawtypes") public class CustomNBTUtils { - - public enum TagClass { - CompoundTagClass(CompoundTag.class), - ByteTagClass(ByteTag.class), - ShortTagClass(ShortTag.class), - IntTagClass(IntTag.class), - LongTagClass(LongTag.class), - FloatTagClass(FloatTag.class), - DoubleTagClass(DoubleTag.class), - ByteArrayTagClass(ByteArrayTag.class), - IntArrayTagClass(IntArrayTag.class), - LongArrayTagClass(LongArrayTag.class), - StringTagClass(StringTag.class), - ListTagClass(ListTag.class); - - Class clazz; - - TagClass(Class clazz) { - this.clazz = clazz; - } - - public Class getTagClass() { - return clazz; - } - } - - public static Class getClassFromName(String name) { - for (TagClass clazz : TagClass.values()) { - if (clazz.getTagClass().getSimpleName().equals(name)) { - return clazz.getTagClass(); - } - } - return null; - } - - public static CompoundTag getCompoundTagFromJson(JSONObject json) { - CompoundTag tag = new CompoundTag(); - - for (Object obj : json.keySet()) { - String key = (String) obj; - JSONObject inside = (JSONObject) json.get(key); - String type = (String) inside.get("type"); - - switch (type) { - case "ByteTag": - tag.putByte(key, (byte) (long) inside.get("value")); - break; - case "ShortTag": - tag.putShort(key, (short) (long) inside.get("value")); - break; - case "IntTag": - tag.putInt(key, (int) (long) inside.get("value")); - break; - case "LongTag": - tag.putLong(key, (long) inside.get("value")); - break; - case "FloatTag": - tag.putFloat(key, inside.get("value") instanceof Long ? (float) (long) inside.get("value") : (float) (double) inside.get("value")); - break; - case "DoubleTag": - tag.putDouble(key, inside.get("value") instanceof Long ? (double) (long) inside.get("value") : (double) inside.get("value")); - break; - case "ByteArrayTag": - tag.putByteArray(key, CustomArrayUtils.longArrayToByteArray((long[]) inside.get("value"))); - break; - case "IntArrayTag": - tag.putIntArray(key, CustomArrayUtils.longArrayToIntArray((long[]) inside.get("value"))); - break; - case "LongArrayTag": - tag.putLongArray(key, (long[]) inside.get("value")); - break; - case "StringTag": - tag.putString(key, (String) inside.get("value")); - break; - case "CompoundTag": - tag.put(key, getCompoundTagFromJson((JSONObject) inside.get("value"))); - break; - case "ListTag": - tag.put(key, getListTagFromJson((JSONObject) inside.get("value"))); - break; - } - } - - return tag; - } - - public static ListTag getListTagFromJson(JSONObject json) { - String type = (String) json.get("type"); - JSONArray array = (JSONArray) json.get("list"); - - ListTag listTag = ListTag.createUnchecked(getClassFromName(type)); - - switch (type) { - case "ByteTag": - for (Object obj : array) { - listTag.addByte((byte) (long) obj); - } - break; - case "ShortTag": - for (Object obj : array) { - listTag.addShort((short) (long) obj); - } - break; - case "IntTag": - for (Object obj : array) { - listTag.addInt((int) (long) obj); - } - break; - case "LongTag": - for (Object obj : array) { - listTag.addLong((long) obj); - } - break; - case "FloatTag": - for (Object obj : array) { - listTag.addFloat(obj instanceof Long ? (float) (long) obj : (float) (double) obj); - } - break; - case "DoubleTag": - for (Object obj : array) { - listTag.addDouble(obj instanceof Long ? (double) (long) obj : (double) obj); - } - break; - case "ByteArrayTag": - for (Object obj : array) { - listTag.addByteArray(CustomArrayUtils.longArrayToByteArray((long[]) obj)); - } - break; - case "IntArrayTag": - for (Object obj : array) { - listTag.addIntArray(CustomArrayUtils.longArrayToIntArray((long[]) obj)); - } - break; - case "LongArrayTag": - for (Object obj : array) { - listTag.addLongArray((long[]) obj); - } - break; - case "StringTag": - for (Object obj : array) { - listTag.addString((String) obj); - } - break; - case "CompoundTag": - for (Object obj : array) { - listTag.asCompoundTagList().add(getCompoundTagFromJson((JSONObject) obj)); - } - break; - case "ListTag": - for (Object obj : array) { - listTag.asListTagList().add(getListTagFromJson((JSONObject) obj)); - } - break; - } - - return listTag; - } + + public static Class getClassFromName(String name) { + for (TagClass clazz : TagClass.values()) { + if (clazz.getTagClass().getSimpleName().equals(name)) { + return clazz.getTagClass(); + } + } + return null; + } + + public static CompoundTag getCompoundTagFromJson(JSONObject json) { + CompoundTag tag = new CompoundTag(); + + for (Object obj : json.keySet()) { + String key = (String) obj; + JSONObject inside = (JSONObject) json.get(key); + String type = (String) inside.get("type"); + + switch (type) { + case "ByteTag": + tag.putByte(key, (byte) (long) inside.get("value")); + break; + case "ShortTag": + tag.putShort(key, (short) (long) inside.get("value")); + break; + case "IntTag": + tag.putInt(key, (int) (long) inside.get("value")); + break; + case "LongTag": + tag.putLong(key, (long) inside.get("value")); + break; + case "FloatTag": + tag.putFloat(key, inside.get("value") instanceof Long ? (float) (long) inside.get("value") : (float) (double) inside.get("value")); + break; + case "DoubleTag": + tag.putDouble(key, inside.get("value") instanceof Long ? (double) (long) inside.get("value") : (double) inside.get("value")); + break; + case "ByteArrayTag": + tag.putByteArray(key, CustomArrayUtils.longArrayToByteArray((long[]) inside.get("value"))); + break; + case "IntArrayTag": + tag.putIntArray(key, CustomArrayUtils.longArrayToIntArray((long[]) inside.get("value"))); + break; + case "LongArrayTag": + tag.putLongArray(key, (long[]) inside.get("value")); + break; + case "StringTag": + tag.putString(key, (String) inside.get("value")); + break; + case "CompoundTag": + tag.put(key, getCompoundTagFromJson((JSONObject) inside.get("value"))); + break; + case "ListTag": + tag.put(key, getListTagFromJson((JSONObject) inside.get("value"))); + break; + } + } + + return tag; + } + + public static ListTag getListTagFromJson(JSONObject json) { + String type = (String) json.get("type"); + JSONArray array = (JSONArray) json.get("list"); + + ListTag listTag = ListTag.createUnchecked(getClassFromName(type)); + + switch (type) { + case "ByteTag": + for (Object obj : array) { + listTag.addByte((byte) (long) obj); + } + break; + case "ShortTag": + for (Object obj : array) { + listTag.addShort((short) (long) obj); + } + break; + case "IntTag": + for (Object obj : array) { + listTag.addInt((int) (long) obj); + } + break; + case "LongTag": + for (Object obj : array) { + listTag.addLong((long) obj); + } + break; + case "FloatTag": + for (Object obj : array) { + listTag.addFloat(obj instanceof Long ? (float) (long) obj : (float) (double) obj); + } + break; + case "DoubleTag": + for (Object obj : array) { + listTag.addDouble(obj instanceof Long ? (double) (long) obj : (double) obj); + } + break; + case "ByteArrayTag": + for (Object obj : array) { + listTag.addByteArray(CustomArrayUtils.longArrayToByteArray((long[]) obj)); + } + break; + case "IntArrayTag": + for (Object obj : array) { + listTag.addIntArray(CustomArrayUtils.longArrayToIntArray((long[]) obj)); + } + break; + case "LongArrayTag": + for (Object obj : array) { + listTag.addLongArray((long[]) obj); + } + break; + case "StringTag": + for (Object obj : array) { + listTag.addString((String) obj); + } + break; + case "CompoundTag": + for (Object obj : array) { + listTag.asCompoundTagList().add(getCompoundTagFromJson((JSONObject) obj)); + } + break; + case "ListTag": + for (Object obj : array) { + listTag.asListTagList().add(getListTagFromJson((JSONObject) obj)); + } + break; + } + + return listTag; + } + + public enum TagClass { + CompoundTagClass(CompoundTag.class), + ByteTagClass(ByteTag.class), + ShortTagClass(ShortTag.class), + IntTagClass(IntTag.class), + LongTagClass(LongTag.class), + FloatTagClass(FloatTag.class), + DoubleTagClass(DoubleTag.class), + ByteArrayTagClass(ByteArrayTag.class), + IntArrayTagClass(IntArrayTag.class), + LongArrayTagClass(LongArrayTag.class), + StringTagClass(StringTag.class), + ListTagClass(ListTag.class); + + Class clazz; + + TagClass(Class clazz) { + this.clazz = clazz; + } + + public Class getTagClass() { + return clazz; + } + } } diff --git a/src/main/java/com/loohp/limbo/utils/CustomStringUtils.java b/src/main/java/com/loohp/limbo/utils/CustomStringUtils.java index 8d716c2..899742e 100644 --- a/src/main/java/com/loohp/limbo/utils/CustomStringUtils.java +++ b/src/main/java/com/loohp/limbo/utils/CustomStringUtils.java @@ -5,63 +5,63 @@ import java.util.Arrays; import java.util.List; public class CustomStringUtils { - - public static boolean arrayContains(String compare, String[] args, boolean IgnoreCase) { - return IgnoreCase ? Arrays.asList(args).stream().anyMatch(each -> each.equalsIgnoreCase(compare)) : Arrays.asList(args).stream().anyMatch(each -> each.equals(compare)); - } - - public static boolean arrayContains(String compare, String[] args) { - return arrayContains(compare, args, true); - } - - public static String[] splitStringToArgs(String str) { - List tokens = new ArrayList(); - StringBuilder sb = new StringBuilder(); - boolean insideQuote = false; + public static boolean arrayContains(String compare, String[] args, boolean IgnoreCase) { + return IgnoreCase ? Arrays.asList(args).stream().anyMatch(each -> each.equalsIgnoreCase(compare)) : Arrays.asList(args).stream().anyMatch(each -> each.equals(compare)); + } - for (char c : str.toCharArray()) { - if (c == '"') { - insideQuote = !insideQuote; - } else if (c == ' ' && !insideQuote) { - if (sb.length() > 0) { - tokens.add(sb.toString()); - } - sb.delete(0, sb.length()); - } else { - sb.append(c); - } - } - tokens.add(sb.toString()); - - return tokens.toArray(new String[tokens.size()]); - } - - public static int getIndexOfArg(String str, int ordinal) { - StringBuilder sb = new StringBuilder(); + public static boolean arrayContains(String compare, String[] args) { + return arrayContains(compare, args, true); + } + + public static String[] splitStringToArgs(String str) { + List tokens = new ArrayList(); + StringBuilder sb = new StringBuilder(); + + boolean insideQuote = false; + + for (char c : str.toCharArray()) { + if (c == '"') { + insideQuote = !insideQuote; + } else if (c == ' ' && !insideQuote) { + if (sb.length() > 0) { + tokens.add(sb.toString()); + } + sb.delete(0, sb.length()); + } else { + sb.append(c); + } + } + tokens.add(sb.toString()); + + return tokens.toArray(new String[tokens.size()]); + } + + public static int getIndexOfArg(String str, int ordinal) { + StringBuilder sb = new StringBuilder(); + + boolean insideQuote = false; + + int pos = 0; + int found = 0; + for (char c : str.toCharArray()) { + if (c == '"') { + insideQuote = !insideQuote; + } else if (c == ' ' && !insideQuote) { + if (sb.length() > 0) { + found++; + } + sb.delete(0, sb.length()); + } else { + sb.append(c); + } + if (found == ordinal) { + return pos; + } + pos++; + } + + return -1; + } - boolean insideQuote = false; - - int pos = 0; - int found = 0; - for (char c : str.toCharArray()) { - if (c == '"') { - insideQuote = !insideQuote; - } else if (c == ' ' && !insideQuote) { - if (sb.length() > 0) { - found++; - } - sb.delete(0, sb.length()); - } else { - sb.append(c); - } - if (found == ordinal) { - return pos; - } - pos++; - } - - return -1; - } - } diff --git a/src/main/java/com/loohp/limbo/utils/DataTypeIO.java b/src/main/java/com/loohp/limbo/utils/DataTypeIO.java index dbf376f..25ad941 100644 --- a/src/main/java/com/loohp/limbo/utils/DataTypeIO.java +++ b/src/main/java/com/loohp/limbo/utils/DataTypeIO.java @@ -1,5 +1,10 @@ package com.loohp.limbo.utils; +import com.loohp.limbo.world.BlockPosition; +import net.querz.nbt.io.NBTOutputStream; +import net.querz.nbt.tag.CompoundTag; +import net.querz.nbt.tag.Tag; + import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -7,129 +12,123 @@ import java.io.IOException; import java.nio.charset.Charset; import java.util.UUID; -import com.loohp.limbo.world.BlockPosition; - -import net.querz.nbt.io.NBTOutputStream; -import net.querz.nbt.tag.CompoundTag; -import net.querz.nbt.tag.Tag; - public class DataTypeIO { - - public static void writeBlockPosition(DataOutputStream out, BlockPosition position) throws IOException { + + public static void writeBlockPosition(DataOutputStream out, BlockPosition position) throws IOException { out.writeLong(((position.getX() & 0x3FFFFFF) << 38) | ((position.getZ() & 0x3FFFFFF) << 12) | (position.getY() & 0xFFF)); - } - - public static void writeUUID(DataOutputStream out, UUID uuid) throws IOException { - out.writeLong(uuid.getMostSignificantBits()); - out.writeLong(uuid.getLeastSignificantBits()); - } - - public static void writeCompoundTag(DataOutputStream out, CompoundTag tag) throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - DataOutputStream output = new DataOutputStream(buffer); - new NBTOutputStream(output).writeTag(tag, Tag.DEFAULT_MAX_DEPTH); - - byte[] b = buffer.toByteArray(); - out.write(b); - } - - public static String readString(DataInputStream in, Charset charset) throws IOException { - int length = readVarInt(in); + } - if (length == -1) { - throw new IOException("Premature end of stream."); - } + public static void writeUUID(DataOutputStream out, UUID uuid) throws IOException { + out.writeLong(uuid.getMostSignificantBits()); + out.writeLong(uuid.getLeastSignificantBits()); + } - byte[] b = new byte[length]; - in.readFully(b); - return new String(b, charset); - } - - public static int getStringLength(String string, Charset charset) throws IOException { - byte[] bytes = string.getBytes(charset); - return bytes.length; - } - - public static void writeString(DataOutputStream out, String string, Charset charset) throws IOException { - byte[] bytes = string.getBytes(charset); - writeVarInt(out, bytes.length); - out.write(bytes); - } - - public static int readVarInt(DataInputStream in) throws IOException { - int numRead = 0; - int result = 0; - byte read; - do { - read = in.readByte(); - int value = (read & 0b01111111); - result |= (value << (7 * numRead)); + public static void writeCompoundTag(DataOutputStream out, CompoundTag tag) throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - numRead++; - if (numRead > 5) { - throw new RuntimeException("VarInt is too big"); - } - } while ((read & 0b10000000) != 0); + DataOutputStream output = new DataOutputStream(buffer); + new NBTOutputStream(output).writeTag(tag, Tag.DEFAULT_MAX_DEPTH); - return result; - } - - public static void writeVarInt(DataOutputStream out, int value) throws IOException { - do { - byte temp = (byte)(value & 0b01111111); - // Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone - value >>>= 7; - if (value != 0) { - temp |= 0b10000000; - } - out.writeByte(temp); - } while (value != 0); - } - - public static int getVarIntLength(int value) throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - DataOutputStream out = new DataOutputStream(buffer); - do { - byte temp = (byte)(value & 0b01111111); - // Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone - value >>>= 7; - if (value != 0) { - temp |= 0b10000000; - } - out.writeByte(temp); - } while (value != 0); - return buffer.toByteArray().length; - } - - public static long readVarLong(DataInputStream in) throws IOException { - int numRead = 0; - long result = 0; - byte read; - do { - read = in.readByte(); - long value = (read & 0b01111111); - result |= (value << (7 * numRead)); + byte[] b = buffer.toByteArray(); + out.write(b); + } - numRead++; - if (numRead > 10) { - throw new RuntimeException("VarLong is too big"); - } - } while ((read & 0b10000000) != 0); + public static String readString(DataInputStream in, Charset charset) throws IOException { + int length = readVarInt(in); - return result; - } - - public static void writeVarLong(DataOutputStream out, long value) throws IOException { - do { - byte temp = (byte)(value & 0b01111111); - // Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone - value >>>= 7; - if (value != 0) { - temp |= 0b10000000; - } - out.writeByte(temp); - } while (value != 0); - } + if (length == -1) { + throw new IOException("Premature end of stream."); + } + + byte[] b = new byte[length]; + in.readFully(b); + return new String(b, charset); + } + + public static int getStringLength(String string, Charset charset) throws IOException { + byte[] bytes = string.getBytes(charset); + return bytes.length; + } + + public static void writeString(DataOutputStream out, String string, Charset charset) throws IOException { + byte[] bytes = string.getBytes(charset); + writeVarInt(out, bytes.length); + out.write(bytes); + } + + public static int readVarInt(DataInputStream in) throws IOException { + int numRead = 0; + int result = 0; + byte read; + do { + read = in.readByte(); + int value = (read & 0b01111111); + result |= (value << (7 * numRead)); + + numRead++; + if (numRead > 5) { + throw new RuntimeException("VarInt is too big"); + } + } while ((read & 0b10000000) != 0); + + return result; + } + + public static void writeVarInt(DataOutputStream out, int value) throws IOException { + do { + byte temp = (byte) (value & 0b01111111); + // Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone + value >>>= 7; + if (value != 0) { + temp |= 0b10000000; + } + out.writeByte(temp); + } while (value != 0); + } + + public static int getVarIntLength(int value) throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + DataOutputStream out = new DataOutputStream(buffer); + do { + byte temp = (byte) (value & 0b01111111); + // Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone + value >>>= 7; + if (value != 0) { + temp |= 0b10000000; + } + out.writeByte(temp); + } while (value != 0); + return buffer.toByteArray().length; + } + + public static long readVarLong(DataInputStream in) throws IOException { + int numRead = 0; + long result = 0; + byte read; + do { + read = in.readByte(); + long value = (read & 0b01111111); + result |= (value << (7 * numRead)); + + numRead++; + if (numRead > 10) { + throw new RuntimeException("VarLong is too big"); + } + } while ((read & 0b10000000) != 0); + + return result; + } + + public static void writeVarLong(DataOutputStream out, long value) throws IOException { + do { + byte temp = (byte) (value & 0b01111111); + // Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone + value >>>= 7; + if (value != 0) { + temp |= 0b10000000; + } + out.writeByte(temp); + } while (value != 0); + } } diff --git a/src/main/java/com/loohp/limbo/utils/DeclareCommands.java b/src/main/java/com/loohp/limbo/utils/DeclareCommands.java index 4c58e2a..58ea4d1 100644 --- a/src/main/java/com/loohp/limbo/utils/DeclareCommands.java +++ b/src/main/java/com/loohp/limbo/utils/DeclareCommands.java @@ -1,56 +1,56 @@ package com.loohp.limbo.utils; +import com.loohp.limbo.Limbo; +import com.loohp.limbo.commands.CommandSender; +import com.loohp.limbo.server.packets.PacketPlayOutDeclareCommands; + import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.List; -import com.loohp.limbo.Limbo; -import com.loohp.limbo.server.packets.PacketPlayOutDeclareCommands; -import com.loohp.limbo.commands.CommandSender; - public class DeclareCommands { - - public static PacketPlayOutDeclareCommands getDeclareCommandsPacket(CommandSender sender) throws IOException { - List commands = Limbo.getInstance().getPluginManager().getTabOptions(sender, new String[0]); - - if (commands.isEmpty()) { - return null; - } - - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - DataOutputStream output = new DataOutputStream(buffer); - DataTypeIO.writeVarInt(output, commands.size() * 2 + 1); - - output.writeByte(0); - DataTypeIO.writeVarInt(output, commands.size()); - for (int i = 1; i <= commands.size() * 2; i++) { - DataTypeIO.writeVarInt(output, i++); - } - - int i = 1; - for (String label : commands) { - output.writeByte(1 | 0x04); - DataTypeIO.writeVarInt(output, 1); - DataTypeIO.writeVarInt(output, i + 1); - DataTypeIO.writeString(output, label, StandardCharsets.UTF_8); - i++; - - output.writeByte(2 | 0x04 | 0x10); - DataTypeIO.writeVarInt(output, 1); - DataTypeIO.writeVarInt(output, i); - DataTypeIO.writeString(output, "arg", StandardCharsets.UTF_8); - DataTypeIO.writeString(output, "brigadier:string", StandardCharsets.UTF_8); - DataTypeIO.writeVarInt(output, 0); - DataTypeIO.writeString(output, "minecraft:ask_server", StandardCharsets.UTF_8); - i++; - } - - DataTypeIO.writeVarInt(output, 0); - - return new PacketPlayOutDeclareCommands(buffer.toByteArray()); - } + public static PacketPlayOutDeclareCommands getDeclareCommandsPacket(CommandSender sender) throws IOException { + List commands = Limbo.getInstance().getPluginManager().getTabOptions(sender, new String[0]); + + if (commands.isEmpty()) { + return null; + } + + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + DataOutputStream output = new DataOutputStream(buffer); + + DataTypeIO.writeVarInt(output, commands.size() * 2 + 1); + + output.writeByte(0); + DataTypeIO.writeVarInt(output, commands.size()); + for (int i = 1; i <= commands.size() * 2; i++) { + DataTypeIO.writeVarInt(output, i++); + } + + int i = 1; + for (String label : commands) { + output.writeByte(1 | 0x04); + DataTypeIO.writeVarInt(output, 1); + DataTypeIO.writeVarInt(output, i + 1); + DataTypeIO.writeString(output, label, StandardCharsets.UTF_8); + i++; + + output.writeByte(2 | 0x04 | 0x10); + DataTypeIO.writeVarInt(output, 1); + DataTypeIO.writeVarInt(output, i); + DataTypeIO.writeString(output, "arg", StandardCharsets.UTF_8); + DataTypeIO.writeString(output, "brigadier:string", StandardCharsets.UTF_8); + DataTypeIO.writeVarInt(output, 0); + DataTypeIO.writeString(output, "minecraft:ask_server", StandardCharsets.UTF_8); + i++; + } + + DataTypeIO.writeVarInt(output, 0); + + return new PacketPlayOutDeclareCommands(buffer.toByteArray()); + } } diff --git a/src/main/java/com/loohp/limbo/utils/GameMode.java b/src/main/java/com/loohp/limbo/utils/GameMode.java index 4f66fcb..19133d8 100644 --- a/src/main/java/com/loohp/limbo/utils/GameMode.java +++ b/src/main/java/com/loohp/limbo/utils/GameMode.java @@ -1,44 +1,44 @@ package com.loohp.limbo.utils; public enum GameMode { - - SURVIVAL(0, "survival"), - CREATIVE(1, "creative"), - ADVENTURE(2, "adventure"), - SPECTATOR(3, "spectator"); - - int id; - String name; - - GameMode(int id, String name) { - this.id = id; - this.name = name; - } - - public int getId() { - return id; - } - - public String getName() { - return name; - } - - public static GameMode fromId(int id) { - for (GameMode mode : GameMode.values()) { - if (mode.getId() == id) { - return mode; - } - } - return null; - } - - public static GameMode fromName(String name) { - for (GameMode mode : GameMode.values()) { - if (mode.getName().equalsIgnoreCase(name)) { - return mode; - } - } - return null; - } + + SURVIVAL(0, "survival"), + CREATIVE(1, "creative"), + ADVENTURE(2, "adventure"), + SPECTATOR(3, "spectator"); + + int id; + String name; + + GameMode(int id, String name) { + this.id = id; + this.name = name; + } + + public static GameMode fromId(int id) { + for (GameMode mode : GameMode.values()) { + if (mode.getId() == id) { + return mode; + } + } + return null; + } + + public static GameMode fromName(String name) { + for (GameMode mode : GameMode.values()) { + if (mode.getName().equalsIgnoreCase(name)) { + return mode; + } + } + return null; + } + + public int getId() { + return id; + } + + public String getName() { + return name; + } } diff --git a/src/main/java/com/loohp/limbo/utils/ImageUtils.java b/src/main/java/com/loohp/limbo/utils/ImageUtils.java index 4c3d0de..0d6e6f1 100644 --- a/src/main/java/com/loohp/limbo/utils/ImageUtils.java +++ b/src/main/java/com/loohp/limbo/utils/ImageUtils.java @@ -1,18 +1,17 @@ package com.loohp.limbo.utils; +import javax.imageio.ImageIO; import java.awt.image.RenderedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Base64; -import javax.imageio.ImageIO; - public class ImageUtils { - public static String imgToBase64String(final RenderedImage img, String formatName) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ImageIO.write(img, formatName, out); - return Base64.getEncoder().encodeToString(out.toByteArray()); - } + public static String imgToBase64String(final RenderedImage img, String formatName) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ImageIO.write(img, formatName, out); + return Base64.getEncoder().encodeToString(out.toByteArray()); + } } diff --git a/src/main/java/com/loohp/limbo/utils/MojangAPIUtils.java b/src/main/java/com/loohp/limbo/utils/MojangAPIUtils.java index c1dbf48..f932457 100644 --- a/src/main/java/com/loohp/limbo/utils/MojangAPIUtils.java +++ b/src/main/java/com/loohp/limbo/utils/MojangAPIUtils.java @@ -1,5 +1,6 @@ package com.loohp.limbo.utils; +import javax.net.ssl.HttpsURLConnection; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; @@ -7,87 +8,85 @@ import java.net.URL; import java.util.UUID; import java.util.stream.Collectors; -import javax.net.ssl.HttpsURLConnection; - public class MojangAPIUtils { - - public static class SkinResponse { - String skin; - String signature; - - public SkinResponse(String skin, String signature) { - this.skin = skin; - this.signature = signature; - } - - public String getSkin() { - return skin; - } - - public String getSignature() { - return signature; - } - - } - - public static UUID getOnlineUUIDOfPlayerFromMojang(String username) { - try { - URL url = new URL("https://api.mojang.com/users/profiles/minecraft/" + username); - HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); + public static UUID getOnlineUUIDOfPlayerFromMojang(String username) { + try { + URL url = new URL("https://api.mojang.com/users/profiles/minecraft/" + username); + HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.setUseCaches(false); connection.setDefaultUseCaches(false); connection.addRequestProperty("User-Agent", "Mozilla/5.0"); connection.addRequestProperty("Cache-Control", "no-cache, no-store, must-revalidate"); connection.addRequestProperty("Pragma", "no-cache"); - if (connection.getResponseCode() == HttpsURLConnection.HTTP_OK) { - String reply = new BufferedReader(new InputStreamReader(connection.getInputStream())).readLine(); - if (!reply.contains("\"error\":\"BadRequestException\"")) { - String uuid = reply.split("\"id\":\"")[1].split("\"")[0]; - return UUID.fromString(uuid.replaceFirst("([0-9a-fA-F]{8})([0-9a-fA-F]{4})([0-9a-fA-F]{4})([0-9a-fA-F]{4})([0-9a-fA-F]+)", "$1-$2-$3-$4-$5")); - } else { - return null; - } - } else { - System.err.println("Connection could not be opened (Response code " + connection.getResponseCode() + ", " + connection.getResponseMessage() + ")"); - return null; - } - } catch (IOException e) { - e.printStackTrace(); - return null; - } - } - - public static SkinResponse getSkinFromMojangServer(String username) { - UUID uuid = getOnlineUUIDOfPlayerFromMojang(username); - if (uuid == null) { - return null; - } - return getSkinFromMojangServer(uuid); - } - - public static SkinResponse getSkinFromMojangServer(UUID uuid) { - try { - URL url = new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + uuid.toString() + "?unsigned=false"); - HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); + if (connection.getResponseCode() == HttpsURLConnection.HTTP_OK) { + String reply = new BufferedReader(new InputStreamReader(connection.getInputStream())).readLine(); + if (!reply.contains("\"error\":\"BadRequestException\"")) { + String uuid = reply.split("\"id\":\"")[1].split("\"")[0]; + return UUID.fromString(uuid.replaceFirst("([0-9a-fA-F]{8})([0-9a-fA-F]{4})([0-9a-fA-F]{4})([0-9a-fA-F]{4})([0-9a-fA-F]+)", "$1-$2-$3-$4-$5")); + } else { + return null; + } + } else { + System.err.println("Connection could not be opened (Response code " + connection.getResponseCode() + ", " + connection.getResponseMessage() + ")"); + return null; + } + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + public static SkinResponse getSkinFromMojangServer(String username) { + UUID uuid = getOnlineUUIDOfPlayerFromMojang(username); + if (uuid == null) { + return null; + } + return getSkinFromMojangServer(uuid); + } + + public static SkinResponse getSkinFromMojangServer(UUID uuid) { + try { + URL url = new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + uuid.toString() + "?unsigned=false"); + HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.setUseCaches(false); connection.setDefaultUseCaches(false); connection.addRequestProperty("User-Agent", "Mozilla/5.0"); connection.addRequestProperty("Cache-Control", "no-cache, no-store, must-revalidate"); connection.addRequestProperty("Pragma", "no-cache"); - if (connection.getResponseCode() == HttpsURLConnection.HTTP_OK) { - String reply = String.join("", new BufferedReader(new InputStreamReader(connection.getInputStream())).lines().collect(Collectors.toList())).replace(" ", ""); - String skin = reply.split("\"value\":\"")[1].split("\"")[0]; - String signature = reply.split("\"signature\":\"")[1].split("\"")[0]; - return new SkinResponse(skin, signature); - } else { - System.err.println("Connection could not be opened (Response code " + connection.getResponseCode() + ", " + connection.getResponseMessage() + ")"); - return null; - } - } catch (IOException e) { - e.printStackTrace(); - return null; - } - } + if (connection.getResponseCode() == HttpsURLConnection.HTTP_OK) { + String reply = String.join("", new BufferedReader(new InputStreamReader(connection.getInputStream())).lines().collect(Collectors.toList())).replace(" ", ""); + String skin = reply.split("\"value\":\"")[1].split("\"")[0]; + String signature = reply.split("\"signature\":\"")[1].split("\"")[0]; + return new SkinResponse(skin, signature); + } else { + System.err.println("Connection could not be opened (Response code " + connection.getResponseCode() + ", " + connection.getResponseMessage() + ")"); + return null; + } + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + public static class SkinResponse { + + String skin; + String signature; + + public SkinResponse(String skin, String signature) { + this.skin = skin; + this.signature = signature; + } + + public String getSkin() { + return skin; + } + + public String getSignature() { + return signature; + } + + } } diff --git a/src/main/java/com/loohp/limbo/utils/NamespacedKey.java b/src/main/java/com/loohp/limbo/utils/NamespacedKey.java index f5cf13c..28f33c5 100644 --- a/src/main/java/com/loohp/limbo/utils/NamespacedKey.java +++ b/src/main/java/com/loohp/limbo/utils/NamespacedKey.java @@ -1,74 +1,71 @@ package com.loohp.limbo.utils; public class NamespacedKey { - - public static final String MINECRAFT_KEY = "minecraft"; - private String namespace; - private String key; + public static final String MINECRAFT_KEY = "minecraft"; - public NamespacedKey(String namespacedKey) { - int index = namespacedKey.indexOf(":"); - if (index >= 0) { - this.namespace = namespacedKey.substring(0, index); - this.key = namespacedKey.substring(index + 1); - } else { - this.namespace = "minecraft"; - this.key = namespacedKey; - } - } + private final String namespace; + private final String key; - public NamespacedKey(String namespace, String key) { - this.namespace = namespace; - this.key = key; - } - - public static NamespacedKey minecraft(String key) { - return new NamespacedKey(MINECRAFT_KEY, key); - } + public NamespacedKey(String namespacedKey) { + int index = namespacedKey.indexOf(":"); + if (index >= 0) { + this.namespace = namespacedKey.substring(0, index); + this.key = namespacedKey.substring(index + 1); + } else { + this.namespace = "minecraft"; + this.key = namespacedKey; + } + } - public String getNamespace() { - return namespace; - } + public NamespacedKey(String namespace, String key) { + this.namespace = namespace; + this.key = key; + } - public String getKey() { - return key; - } + public static NamespacedKey minecraft(String key) { + return new NamespacedKey(MINECRAFT_KEY, key); + } - @Override - public String toString() { - return namespace + ":" + key; - } + public String getNamespace() { + return namespace; + } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((key == null) ? 0 : key.hashCode()); - result = prime * result + ((namespace == null) ? 0 : namespace.hashCode()); - return result; - } + public String getKey() { + return key; + } - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - NamespacedKey other = (NamespacedKey) obj; - if (key == null) { - if (other.key != null) - return false; - } else if (!key.equals(other.key)) - return false; - if (namespace == null) { - if (other.namespace != null) - return false; - } else if (!namespace.equals(other.namespace)) - return false; - return true; - } + @Override + public String toString() { + return namespace + ":" + key; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((key == null) ? 0 : key.hashCode()); + result = prime * result + ((namespace == null) ? 0 : namespace.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + NamespacedKey other = (NamespacedKey) obj; + if (key == null) { + if (other.key != null) + return false; + } else if (!key.equals(other.key)) + return false; + if (namespace == null) { + return other.namespace == null; + } else return namespace.equals(other.namespace); + } } diff --git a/src/main/java/com/loohp/limbo/utils/NetworkUtils.java b/src/main/java/com/loohp/limbo/utils/NetworkUtils.java index 07f621c..a8ed766 100644 --- a/src/main/java/com/loohp/limbo/utils/NetworkUtils.java +++ b/src/main/java/com/loohp/limbo/utils/NetworkUtils.java @@ -5,32 +5,32 @@ import java.net.DatagramSocket; import java.net.ServerSocket; public class NetworkUtils { - - public static boolean available(int port) { - ServerSocket ss = null; - DatagramSocket ds = null; - try { - ss = new ServerSocket(port); - ss.setReuseAddress(true); - ds = new DatagramSocket(port); - ds.setReuseAddress(true); - return true; - } catch (IOException e) { - e.printStackTrace(); - } finally { - if (ds != null) { - ds.close(); - } - if (ss != null) { - try { - ss.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - return false; - } + public static boolean available(int port) { + ServerSocket ss = null; + DatagramSocket ds = null; + try { + ss = new ServerSocket(port); + ss.setReuseAddress(true); + ds = new DatagramSocket(port); + ds.setReuseAddress(true); + return true; + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (ds != null) { + ds.close(); + } + + if (ss != null) { + try { + ss.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return false; + } } diff --git a/src/main/java/com/loohp/limbo/utils/NumberConversions.java b/src/main/java/com/loohp/limbo/utils/NumberConversions.java index cf06125..88d2863 100644 --- a/src/main/java/com/loohp/limbo/utils/NumberConversions.java +++ b/src/main/java/com/loohp/limbo/utils/NumberConversions.java @@ -4,7 +4,8 @@ package com.loohp.limbo.utils; * Utils for casting number types to other number types */ public final class NumberConversions { - private NumberConversions() {} + private NumberConversions() { + } public static int floor(double num) { final int floor = (int) num; diff --git a/src/main/java/com/loohp/limbo/utils/Rotation3f.java b/src/main/java/com/loohp/limbo/utils/Rotation3f.java index f05a83e..6801683 100644 --- a/src/main/java/com/loohp/limbo/utils/Rotation3f.java +++ b/src/main/java/com/loohp/limbo/utils/Rotation3f.java @@ -1,77 +1,74 @@ package com.loohp.limbo.utils; public class Rotation3f { - - private double x; - private double y; - private double z; - - public Rotation3f(double x, double y, double z) { - this.x = x; - this.y = y; - this.z = z; - } - public double getX() { - return x; - } + private double x; + private double y; + private double z; - public void setX(double x) { - this.x = x; - } + public Rotation3f(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } - public double getY() { - return y; - } + public double getX() { + return x; + } - public void setY(double y) { - this.y = y; - } + public void setX(double x) { + this.x = x; + } - public double getZ() { - return z; - } + public double getY() { + return y; + } - public void setZ(double z) { - this.z = z; - } + public void setY(double y) { + this.y = y; + } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - long temp; - temp = Double.doubleToLongBits(x); - result = prime * result + (int) (temp ^ (temp >>> 32)); - temp = Double.doubleToLongBits(y); - result = prime * result + (int) (temp ^ (temp >>> 32)); - temp = Double.doubleToLongBits(z); - result = prime * result + (int) (temp ^ (temp >>> 32)); - return result; - } + public double getZ() { + return z; + } - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - Rotation3f other = (Rotation3f) obj; - if (Double.doubleToLongBits(x) != Double.doubleToLongBits(other.x)) { - return false; - } - if (Double.doubleToLongBits(y) != Double.doubleToLongBits(other.y)) { - return false; - } - if (Double.doubleToLongBits(z) != Double.doubleToLongBits(other.z)) { - return false; - } - return true; - } + public void setZ(double z) { + this.z = z; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + long temp; + temp = Double.doubleToLongBits(x); + result = prime * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(y); + result = prime * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(z); + result = prime * result + (int) (temp ^ (temp >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Rotation3f other = (Rotation3f) obj; + if (Double.doubleToLongBits(x) != Double.doubleToLongBits(other.x)) { + return false; + } + if (Double.doubleToLongBits(y) != Double.doubleToLongBits(other.y)) { + return false; + } + return Double.doubleToLongBits(z) == Double.doubleToLongBits(other.z); + } } diff --git a/src/main/java/com/loohp/limbo/utils/SchematicConvertionUtils.java b/src/main/java/com/loohp/limbo/utils/SchematicConvertionUtils.java index b9d8c2f..d18da6c 100644 --- a/src/main/java/com/loohp/limbo/utils/SchematicConvertionUtils.java +++ b/src/main/java/com/loohp/limbo/utils/SchematicConvertionUtils.java @@ -3,39 +3,39 @@ package com.loohp.limbo.utils; import net.querz.nbt.tag.CompoundTag; public class SchematicConvertionUtils { - - public static CompoundTag toTileEntityTag(CompoundTag tag) { - int[] pos = tag.getIntArray("Pos"); - tag.remove("Pos"); - tag.remove("Id"); - tag.putInt("x", pos[0]); - tag.putInt("y", pos[1]); - tag.putInt("z", pos[2]); - return tag; - } - - public static CompoundTag toBlockTag(String input) { - int index = input.indexOf("["); - CompoundTag tag = new CompoundTag(); - if (index < 0) { - tag.putString("Name", new NamespacedKey(input).toString()); - return tag; - } - - tag.putString("Name", new NamespacedKey(input.substring(0, index)).toString()); - - String[] states = input.substring(index + 1, input.lastIndexOf("]")).replace(" ", "").split(","); - - CompoundTag properties = new CompoundTag(); - for (String state : states) { - String key = state.substring(0, state.indexOf("=")); - String value = state.substring(state.indexOf("=") + 1); - properties.putString(key, value); - } - - tag.put("Properties", properties); - return tag; - } + public static CompoundTag toTileEntityTag(CompoundTag tag) { + int[] pos = tag.getIntArray("Pos"); + tag.remove("Pos"); + tag.remove("Id"); + tag.putInt("x", pos[0]); + tag.putInt("y", pos[1]); + tag.putInt("z", pos[2]); + return tag; + } + + public static CompoundTag toBlockTag(String input) { + int index = input.indexOf("["); + CompoundTag tag = new CompoundTag(); + if (index < 0) { + tag.putString("Name", new NamespacedKey(input).toString()); + return tag; + } + + tag.putString("Name", new NamespacedKey(input.substring(0, index)).toString()); + + String[] states = input.substring(index + 1, input.lastIndexOf("]")).replace(" ", "").split(","); + + CompoundTag properties = new CompoundTag(); + for (String state : states) { + String key = state.substring(0, state.indexOf("=")); + String value = state.substring(state.indexOf("=") + 1); + properties.putString(key, value); + } + + tag.put("Properties", properties); + + return tag; + } } diff --git a/src/main/java/com/loohp/limbo/utils/YamlOrder.java b/src/main/java/com/loohp/limbo/utils/YamlOrder.java index 8b2a16b..3eff3ad 100644 --- a/src/main/java/com/loohp/limbo/utils/YamlOrder.java +++ b/src/main/java/com/loohp/limbo/utils/YamlOrder.java @@ -1,5 +1,9 @@ package com.loohp.limbo.utils; +import org.yaml.snakeyaml.error.YAMLException; +import org.yaml.snakeyaml.introspector.*; +import org.yaml.snakeyaml.util.PlatformFeatureDetector; + import java.beans.FeatureDescriptor; import java.beans.IntrospectionException; import java.beans.Introspector; @@ -7,31 +11,17 @@ import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; - -import org.yaml.snakeyaml.error.YAMLException; -import org.yaml.snakeyaml.introspector.BeanAccess; -import org.yaml.snakeyaml.introspector.FieldProperty; -import org.yaml.snakeyaml.introspector.MethodProperty; -import org.yaml.snakeyaml.introspector.MissingProperty; -import org.yaml.snakeyaml.introspector.Property; -import org.yaml.snakeyaml.introspector.PropertyUtils; -import org.yaml.snakeyaml.util.PlatformFeatureDetector; +import java.util.*; public class YamlOrder extends PropertyUtils { + private static final String TRANSIENT = "transient"; private final Map, Map> propertiesCache = new HashMap, Map>(); private final Map, Set> readableProperties = new HashMap, Set>(); private BeanAccess beanAccess = BeanAccess.DEFAULT; private boolean allowReadOnlyProperties = false; private boolean skipMissingProperties = false; - - private PlatformFeatureDetector platformFeatureDetector; + private final PlatformFeatureDetector platformFeatureDetector; public YamlOrder() { this(new PlatformFeatureDetector()); @@ -100,8 +90,6 @@ public class YamlOrder extends PropertyUtils { return properties; } - private static final String TRANSIENT = "transient"; - private boolean isTransient(FeatureDescriptor fd) { return Boolean.TRUE.equals(fd.getValue(TRANSIENT)); } @@ -160,6 +148,10 @@ public class YamlOrder extends PropertyUtils { } } + public boolean isAllowReadOnlyProperties() { + return allowReadOnlyProperties; + } + public void setAllowReadOnlyProperties(boolean allowReadOnlyProperties) { if (this.allowReadOnlyProperties != allowReadOnlyProperties) { this.allowReadOnlyProperties = allowReadOnlyProperties; @@ -167,8 +159,8 @@ public class YamlOrder extends PropertyUtils { } } - public boolean isAllowReadOnlyProperties() { - return allowReadOnlyProperties; + public boolean isSkipMissingProperties() { + return skipMissingProperties; } public void setSkipMissingProperties(boolean skipMissingProperties) { @@ -177,8 +169,4 @@ public class YamlOrder extends PropertyUtils { readableProperties.clear(); } } - - public boolean isSkipMissingProperties() { - return skipMissingProperties; - } } \ No newline at end of file diff --git a/src/main/java/com/loohp/limbo/world/BlockPosition.java b/src/main/java/com/loohp/limbo/world/BlockPosition.java index b9c663a..dbb7762 100644 --- a/src/main/java/com/loohp/limbo/world/BlockPosition.java +++ b/src/main/java/com/loohp/limbo/world/BlockPosition.java @@ -3,29 +3,29 @@ package com.loohp.limbo.world; import com.loohp.limbo.location.Location; public class BlockPosition { - private int x; - private int y; - private int z; + private final int x; + private final int y; + private final int z; - public BlockPosition(int x, int y, int z) { - this.x = x; - this.y = y; - this.z = z; - } + public BlockPosition(int x, int y, int z) { + this.x = x; + this.y = y; + this.z = z; + } - public int getX() { - return this.x; - } + public static BlockPosition from(Location location) { + return new BlockPosition((int) Math.floor(location.getX()), (int) Math.floor(location.getY()), (int) Math.floor(location.getZ())); + } - public int getY() { - return this.y; - } + public int getX() { + return this.x; + } - public int getZ() { - return this.z; - } - - public static BlockPosition from(Location location) { - return new BlockPosition((int) Math.floor(location.getX()), (int) Math.floor(location.getY()), (int) Math.floor(location.getZ())); - } + public int getY() { + return this.y; + } + + public int getZ() { + return this.z; + } } diff --git a/src/main/java/com/loohp/limbo/world/BlockState.java b/src/main/java/com/loohp/limbo/world/BlockState.java index 2237332..9772f6f 100644 --- a/src/main/java/com/loohp/limbo/world/BlockState.java +++ b/src/main/java/com/loohp/limbo/world/BlockState.java @@ -1,93 +1,87 @@ package com.loohp.limbo.world; +import com.loohp.limbo.utils.NamespacedKey; +import net.querz.nbt.tag.CompoundTag; +import net.querz.nbt.tag.StringTag; +import net.querz.nbt.tag.Tag; + import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; -import com.loohp.limbo.utils.NamespacedKey; - -import net.querz.nbt.tag.CompoundTag; -import net.querz.nbt.tag.StringTag; -import net.querz.nbt.tag.Tag; - public class BlockState { - - private CompoundTag tag; - - public BlockState(CompoundTag tag) { - this.tag = tag; - } - - public CompoundTag toCompoundTag() { - return tag; - } - - public NamespacedKey getType() { - return new NamespacedKey(tag.getString("Name")); - } - - public void setType(NamespacedKey namespacedKey) { - tag.putString("Name", namespacedKey.toString()); - } - - public Map getProperties() { - Map mapping = new HashMap<>(); - for (Entry> entry : tag.getCompoundTag("Properties")) { - String key = entry.getKey(); - String value = ((StringTag) entry.getValue()).getValue(); - mapping.put(key, value); - } - return mapping; - } - - public String getProperty(String key) { - Tag value = tag.getCompoundTag("Properties").get(key); - return value == null ? null : ((StringTag) value).getValue(); - } - - public void setProperties(Map mapping) { - CompoundTag properties = new CompoundTag(); - for (Entry entry : mapping.entrySet()) { - String key = entry.getKey(); - String value = entry.getValue(); - properties.putString(key, value); - } - tag.put("Properties", properties); - } - - public void setProperty(String key, T value) { - CompoundTag properties = tag.getCompoundTag("Properties"); - properties.putString(key, ((T) value).toString()); - } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((tag == null) ? 0 : tag.hashCode()); - return result; - } + private final CompoundTag tag; - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - BlockState other = (BlockState) obj; - if (tag == null) { - if (other.tag != null) { - return false; - } - } else if (!tag.equals(other.tag)) { - return false; - } - return true; - } + public BlockState(CompoundTag tag) { + this.tag = tag; + } + + public CompoundTag toCompoundTag() { + return tag; + } + + public NamespacedKey getType() { + return new NamespacedKey(tag.getString("Name")); + } + + public void setType(NamespacedKey namespacedKey) { + tag.putString("Name", namespacedKey.toString()); + } + + public Map getProperties() { + Map mapping = new HashMap<>(); + for (Entry> entry : tag.getCompoundTag("Properties")) { + String key = entry.getKey(); + String value = ((StringTag) entry.getValue()).getValue(); + mapping.put(key, value); + } + return mapping; + } + + public void setProperties(Map mapping) { + CompoundTag properties = new CompoundTag(); + for (Entry entry : mapping.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue(); + properties.putString(key, value); + } + tag.put("Properties", properties); + } + + public String getProperty(String key) { + Tag value = tag.getCompoundTag("Properties").get(key); + return value == null ? null : ((StringTag) value).getValue(); + } + + public void setProperty(String key, T value) { + CompoundTag properties = tag.getCompoundTag("Properties"); + properties.putString(key, value.toString()); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((tag == null) ? 0 : tag.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + BlockState other = (BlockState) obj; + if (tag == null) { + return other.tag == null; + } else return tag.equals(other.tag); + } } diff --git a/src/main/java/com/loohp/limbo/world/DimensionRegistry.java b/src/main/java/com/loohp/limbo/world/DimensionRegistry.java index 3a93faf..0e252c9 100644 --- a/src/main/java/com/loohp/limbo/world/DimensionRegistry.java +++ b/src/main/java/com/loohp/limbo/world/DimensionRegistry.java @@ -1,63 +1,57 @@ package com.loohp.limbo.world; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; - +import com.loohp.limbo.Limbo; +import com.loohp.limbo.utils.CustomNBTUtils; +import net.querz.nbt.tag.CompoundTag; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; -import com.loohp.limbo.Limbo; -import com.loohp.limbo.utils.CustomNBTUtils; - -import net.querz.nbt.tag.CompoundTag; +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; public class DimensionRegistry { - - private CompoundTag defaultTag; - private CompoundTag codec; - private File reg; - - public DimensionRegistry() { - this.defaultTag = new CompoundTag(); - - String name = "dimension_registry.json"; + + private CompoundTag defaultTag; + private CompoundTag codec; + private final File reg; + + public DimensionRegistry() { + this.defaultTag = new CompoundTag(); + + String name = "dimension_registry.json"; File file = new File(Limbo.getInstance().getInternalDataFolder(), name); if (!file.exists()) { - try (InputStream in = Limbo.class.getClassLoader().getResourceAsStream(name)) { + try (InputStream in = Limbo.class.getClassLoader().getResourceAsStream(name)) { Files.copy(in, file.toPath()); } catch (IOException e) { - e.printStackTrace(); + e.printStackTrace(); } } - + this.reg = file; - + try (InputStreamReader reader = new InputStreamReader(new FileInputStream(reg), StandardCharsets.UTF_8)) { - JSONObject json = (JSONObject) new JSONParser().parse(reader); - CompoundTag tag = CustomNBTUtils.getCompoundTagFromJson((JSONObject) json.get("value")); - defaultTag = tag; - codec = defaultTag.clone(); - } catch (IOException | ParseException e) { - e.printStackTrace(); - } - } - - public File getFile() { - return reg; - } - - public void resetCodec() { - codec = defaultTag.clone(); - } - - public CompoundTag getCodec() { - return codec; - } + JSONObject json = (JSONObject) new JSONParser().parse(reader); + CompoundTag tag = CustomNBTUtils.getCompoundTagFromJson((JSONObject) json.get("value")); + defaultTag = tag; + codec = defaultTag.clone(); + } catch (IOException | ParseException e) { + e.printStackTrace(); + } + } + + public File getFile() { + return reg; + } + + public void resetCodec() { + codec = defaultTag.clone(); + } + + public CompoundTag getCodec() { + return codec; + } } diff --git a/src/main/java/com/loohp/limbo/world/Environment.java b/src/main/java/com/loohp/limbo/world/Environment.java index b4ac260..b296dcc 100644 --- a/src/main/java/com/loohp/limbo/world/Environment.java +++ b/src/main/java/com/loohp/limbo/world/Environment.java @@ -1,94 +1,88 @@ package com.loohp.limbo.world; +import com.loohp.limbo.utils.NamespacedKey; + import java.util.HashSet; import java.util.Set; -import com.loohp.limbo.utils.NamespacedKey; - public class Environment { - public static final Environment NORMAL = new Environment(new NamespacedKey("minecraft:overworld"), true); - public static final Environment NETHER = new Environment(new NamespacedKey("minecraft:the_nether"), false); - public static final Environment END = new Environment(new NamespacedKey("minecraft:the_end"), false); - - public static final Set REGISTERED_ENVIRONMENTS = new HashSet<>(); + public static final Environment NORMAL = new Environment(new NamespacedKey("minecraft:overworld"), true); + public static final Environment NETHER = new Environment(new NamespacedKey("minecraft:the_nether"), false); + public static final Environment END = new Environment(new NamespacedKey("minecraft:the_end"), false); - public static Environment fromNamespacedKey(NamespacedKey key) { - if (key.equals(NORMAL.getNamespacedKey())) { - return NORMAL; - } else if (key.equals(NETHER.getNamespacedKey())) { - return NETHER; - } else if (key.equals(END.getNamespacedKey())) { - return END; - } - return null; - } - - @Deprecated - public static Environment createCustom(NamespacedKey key) { - return createCustom(key, true); - } - - public static Environment createCustom(NamespacedKey key, boolean hasSkyLight) { - if (REGISTERED_ENVIRONMENTS.stream().anyMatch(each -> each.getNamespacedKey().equals(key))) { - throw new IllegalArgumentException("An Environment is already created with this NamespacedKey"); - } - return new Environment(key, hasSkyLight); - } - - public static Environment getCustom(NamespacedKey key) { - return REGISTERED_ENVIRONMENTS.stream().filter(each -> each.getNamespacedKey().equals(key)).findFirst().orElse(null); - } - - //========================= - - private NamespacedKey key; - private boolean hasSkyLight; - - private Environment(NamespacedKey key, boolean hasSkyLight) { - this.key = key; - this.hasSkyLight = hasSkyLight; - } - - public NamespacedKey getNamespacedKey() { - return key; - } - - public boolean hasSkyLight() { - return hasSkyLight; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + (hasSkyLight ? 1231 : 1237); - result = prime * result + ((key == null) ? 0 : key.hashCode()); - return result; - } + public static final Set REGISTERED_ENVIRONMENTS = new HashSet<>(); + private final NamespacedKey key; + private final boolean hasSkyLight; - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - Environment other = (Environment) obj; - if (hasSkyLight != other.hasSkyLight) { - return false; - } - if (key == null) { - if (other.key != null) { - return false; - } - } else if (!key.equals(other.key)) { - return false; - } - return true; - } + private Environment(NamespacedKey key, boolean hasSkyLight) { + this.key = key; + this.hasSkyLight = hasSkyLight; + } + + public static Environment fromNamespacedKey(NamespacedKey key) { + if (key.equals(NORMAL.getNamespacedKey())) { + return NORMAL; + } else if (key.equals(NETHER.getNamespacedKey())) { + return NETHER; + } else if (key.equals(END.getNamespacedKey())) { + return END; + } + return null; + } + + //========================= + + @Deprecated + public static Environment createCustom(NamespacedKey key) { + return createCustom(key, true); + } + + public static Environment createCustom(NamespacedKey key, boolean hasSkyLight) { + if (REGISTERED_ENVIRONMENTS.stream().anyMatch(each -> each.getNamespacedKey().equals(key))) { + throw new IllegalArgumentException("An Environment is already created with this NamespacedKey"); + } + return new Environment(key, hasSkyLight); + } + + public static Environment getCustom(NamespacedKey key) { + return REGISTERED_ENVIRONMENTS.stream().filter(each -> each.getNamespacedKey().equals(key)).findFirst().orElse(null); + } + + public NamespacedKey getNamespacedKey() { + return key; + } + + public boolean hasSkyLight() { + return hasSkyLight; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (hasSkyLight ? 1231 : 1237); + result = prime * result + ((key == null) ? 0 : key.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Environment other = (Environment) obj; + if (hasSkyLight != other.hasSkyLight) { + return false; + } + if (key == null) { + return other.key == null; + } else return key.equals(other.key); + } } \ No newline at end of file diff --git a/src/main/java/com/loohp/limbo/world/GeneratedBlockDataMappings.java b/src/main/java/com/loohp/limbo/world/GeneratedBlockDataMappings.java index cdd8aef..30a31ff 100644 --- a/src/main/java/com/loohp/limbo/world/GeneratedBlockDataMappings.java +++ b/src/main/java/com/loohp/limbo/world/GeneratedBlockDataMappings.java @@ -1,5 +1,12 @@ package com.loohp.limbo.world; +import com.loohp.limbo.Limbo; +import net.querz.nbt.tag.CompoundTag; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + import java.io.File; import java.io.FileReader; import java.io.IOException; @@ -8,70 +15,61 @@ import java.nio.file.Files; import java.util.HashMap; import java.util.Map; -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; -import org.json.simple.parser.JSONParser; -import org.json.simple.parser.ParseException; - -import com.loohp.limbo.Limbo; - -import net.querz.nbt.tag.CompoundTag; - public class GeneratedBlockDataMappings { - - private static JSONObject globalPalette = new JSONObject(); - - static { - String block = "blocks.json"; + + private static JSONObject globalPalette = new JSONObject(); + + static { + String block = "blocks.json"; File file = new File(Limbo.getInstance().getInternalDataFolder(), block); if (!file.exists()) { - try (InputStream in = Limbo.class.getClassLoader().getResourceAsStream(block)) { + try (InputStream in = Limbo.class.getClassLoader().getResourceAsStream(block)) { Files.copy(in, file.toPath()); } catch (IOException e) { - e.printStackTrace(); + e.printStackTrace(); } } - + try { - globalPalette = (JSONObject) new JSONParser().parse(new FileReader(file)); - } catch (IOException | ParseException e) { - e.printStackTrace(); - } - } - - @SuppressWarnings("unchecked") - public static int getGlobalPaletteIDFromState(CompoundTag tag) { - String blockname = tag.getString("Name"); - - JSONObject data = (JSONObject) globalPalette.get(blockname); - Object obj = data.get("properties"); - if (obj == null) { - return (int) (long) ((JSONObject) ((JSONArray) data.get("states")).get(0)).get("id"); - } - - //JSONObject properties = (JSONObject) obj; - - if (tag.containsKey("Properties")) { - CompoundTag blockProp = tag.get("Properties", CompoundTag.class); - Map blockstate = new HashMap<>(); - for (String key : blockProp.keySet()) { - blockstate.put(key, blockProp.getString(key)); - } - - for (Object entry : (JSONArray) data.get("states")) { - JSONObject jsonobj = (JSONObject) entry; - if (((JSONObject) jsonobj.get("properties")).keySet().stream().allMatch(key -> blockstate.get(key).equals((String) (((JSONObject) jsonobj.get("properties")).get(key))))) { - return (int) (long) jsonobj.get("id"); - } - } - } - - for (Object entry : (JSONArray) data.get("states")) { - if (((JSONObject) entry).containsKey("default") && ((boolean) ((JSONObject) entry).get("default"))) { - return (int) (long) ((JSONObject) entry).get("id"); - } - } - return 0; - } + globalPalette = (JSONObject) new JSONParser().parse(new FileReader(file)); + } catch (IOException | ParseException e) { + e.printStackTrace(); + } + } + + @SuppressWarnings("unchecked") + public static int getGlobalPaletteIDFromState(CompoundTag tag) { + String blockname = tag.getString("Name"); + + JSONObject data = (JSONObject) globalPalette.get(blockname); + Object obj = data.get("properties"); + if (obj == null) { + return (int) (long) ((JSONObject) ((JSONArray) data.get("states")).get(0)).get("id"); + } + + //JSONObject properties = (JSONObject) obj; + + if (tag.containsKey("Properties")) { + CompoundTag blockProp = tag.get("Properties", CompoundTag.class); + Map blockstate = new HashMap<>(); + for (String key : blockProp.keySet()) { + blockstate.put(key, blockProp.getString(key)); + } + + for (Object entry : (JSONArray) data.get("states")) { + JSONObject jsonobj = (JSONObject) entry; + if (((JSONObject) jsonobj.get("properties")).keySet().stream().allMatch(key -> blockstate.get(key).equals(((JSONObject) jsonobj.get("properties")).get(key)))) { + return (int) (long) jsonobj.get("id"); + } + } + } + + for (Object entry : (JSONArray) data.get("states")) { + if (((JSONObject) entry).containsKey("default") && ((boolean) ((JSONObject) entry).get("default"))) { + return (int) (long) ((JSONObject) entry).get("id"); + } + } + return 0; + } } diff --git a/src/main/java/com/loohp/limbo/world/LightEngine.java b/src/main/java/com/loohp/limbo/world/LightEngine.java index c7a022d..0ff0b5d 100644 --- a/src/main/java/com/loohp/limbo/world/LightEngine.java +++ b/src/main/java/com/loohp/limbo/world/LightEngine.java @@ -4,40 +4,40 @@ import java.util.HashMap; import java.util.Map; public abstract class LightEngine { - - private static Map blockLightLevelMapping = new HashMap<>(); - - static { - blockLightLevelMapping.put("minecraft:beacon", (byte) 15); - blockLightLevelMapping.put("minecraft:torch", (byte) 15); - blockLightLevelMapping.put("minecraft:beacon", (byte) 15); - blockLightLevelMapping.put("minecraft:beacon", (byte) 15); - blockLightLevelMapping.put("minecraft:beacon", (byte) 15); - blockLightLevelMapping.put("minecraft:beacon", (byte) 15); - blockLightLevelMapping.put("minecraft:beacon", (byte) 15); - blockLightLevelMapping.put("minecraft:beacon", (byte) 15); - blockLightLevelMapping.put("minecraft:beacon", (byte) 15); - blockLightLevelMapping.put("minecraft:beacon", (byte) 15); - blockLightLevelMapping.put("minecraft:beacon", (byte) 15); - blockLightLevelMapping.put("minecraft:beacon", (byte) 15); - blockLightLevelMapping.put("minecraft:beacon", (byte) 15); - blockLightLevelMapping.put("minecraft:beacon", (byte) 15); - blockLightLevelMapping.put("minecraft:beacon", (byte) 15); - blockLightLevelMapping.put("minecraft:beacon", (byte) 15); - blockLightLevelMapping.put("minecraft:beacon", (byte) 15); - blockLightLevelMapping.put("minecraft:beacon", (byte) 15); - blockLightLevelMapping.put("minecraft:beacon", (byte) 15); - blockLightLevelMapping.put("minecraft:beacon", (byte) 15); - blockLightLevelMapping.put("minecraft:beacon", (byte) 15); - blockLightLevelMapping.put("minecraft:beacon", (byte) 15); - blockLightLevelMapping.put("minecraft:beacon", (byte) 15); - blockLightLevelMapping.put("minecraft:beacon", (byte) 15); - blockLightLevelMapping.put("minecraft:beacon", (byte) 15); - - } - - public static int getBlockLight(BlockState block) { - return blockLightLevelMapping.getOrDefault(block.getType().toString(), (byte) 0); - } + + private static final Map blockLightLevelMapping = new HashMap<>(); + + static { + blockLightLevelMapping.put("minecraft:beacon", (byte) 15); + blockLightLevelMapping.put("minecraft:torch", (byte) 15); + blockLightLevelMapping.put("minecraft:beacon", (byte) 15); + blockLightLevelMapping.put("minecraft:beacon", (byte) 15); + blockLightLevelMapping.put("minecraft:beacon", (byte) 15); + blockLightLevelMapping.put("minecraft:beacon", (byte) 15); + blockLightLevelMapping.put("minecraft:beacon", (byte) 15); + blockLightLevelMapping.put("minecraft:beacon", (byte) 15); + blockLightLevelMapping.put("minecraft:beacon", (byte) 15); + blockLightLevelMapping.put("minecraft:beacon", (byte) 15); + blockLightLevelMapping.put("minecraft:beacon", (byte) 15); + blockLightLevelMapping.put("minecraft:beacon", (byte) 15); + blockLightLevelMapping.put("minecraft:beacon", (byte) 15); + blockLightLevelMapping.put("minecraft:beacon", (byte) 15); + blockLightLevelMapping.put("minecraft:beacon", (byte) 15); + blockLightLevelMapping.put("minecraft:beacon", (byte) 15); + blockLightLevelMapping.put("minecraft:beacon", (byte) 15); + blockLightLevelMapping.put("minecraft:beacon", (byte) 15); + blockLightLevelMapping.put("minecraft:beacon", (byte) 15); + blockLightLevelMapping.put("minecraft:beacon", (byte) 15); + blockLightLevelMapping.put("minecraft:beacon", (byte) 15); + blockLightLevelMapping.put("minecraft:beacon", (byte) 15); + blockLightLevelMapping.put("minecraft:beacon", (byte) 15); + blockLightLevelMapping.put("minecraft:beacon", (byte) 15); + blockLightLevelMapping.put("minecraft:beacon", (byte) 15); + + } + + public static int getBlockLight(BlockState block) { + return blockLightLevelMapping.getOrDefault(block.getType().toString(), (byte) 0); + } } diff --git a/src/main/java/com/loohp/limbo/world/LightEngineBlock.java b/src/main/java/com/loohp/limbo/world/LightEngineBlock.java index 2b1bdb6..a69278c 100644 --- a/src/main/java/com/loohp/limbo/world/LightEngineBlock.java +++ b/src/main/java/com/loohp/limbo/world/LightEngineBlock.java @@ -4,74 +4,93 @@ import java.util.ArrayList; import java.util.List; public class LightEngineBlock extends LightEngine { - - private World world; - private byte[][][] blockLightArray; - - public LightEngineBlock(World world) { - blockLightArray = new byte[world.getChunkWidth() * 16][16 * 18][world.getChunkLength() * 16]; - this.world = world; - updateWorld(); - } - - public void updateWorld() { - blockLightArray = new byte[world.getChunkWidth() * 16][16 * 18][world.getChunkLength() * 16]; - for (int x = 0; x < world.getWidth(); x++) { - for (int y = 0; y < 256; y++) { - for (int z = 0; z < world.getLength(); z++) { - updateBlock(x, y, z); - } - } - } - } - - private void updateBlock(int x, int y, int z) { - BlockState block = world.getBlock(x, y, z); - int lightLevel = getBlockLight(block); - if (lightLevel > 0) { - propergate(lightLevel, x, y, z); - } - } - - private void propergate(int level, int x, int y, int z) { - try { - if (blockLightArray[x][y + 16][z] < level) { - blockLightArray[x][y + 16][z] = (byte) level; - if (level > 1) { - try {propergate(level - 1, x + 1, y, z);} catch (ArrayIndexOutOfBoundsException e) {} - try {propergate(level - 1, x - 1, y, z);} catch (ArrayIndexOutOfBoundsException e) {} - try {propergate(level - 1, x, y + 1, z);} catch (ArrayIndexOutOfBoundsException e) {} - try {propergate(level - 1, x, y - 1, z);} catch (ArrayIndexOutOfBoundsException e) {} - try {propergate(level - 1, x, y, z + 1);} catch (ArrayIndexOutOfBoundsException e) {} - try {propergate(level - 1, x, y, z - 1);} catch (ArrayIndexOutOfBoundsException e) {} - } - } - } catch (ArrayIndexOutOfBoundsException e) {} - } - - public List getBlockLightBitMask(int chunkX, int chunkZ) { - List subchunks = new ArrayList<>(18); - int startX = chunkX * 16; - int endingX = startX + 16; - int startZ = chunkZ * 16; - int endingZ = startZ + 16; - - for (int sub = 17; sub >= 0; sub--) { - List array = new ArrayList<>(); - for (int y = sub * 16; y < (sub * 16) + 16; y++) { - for (int z = startZ; z < endingZ; z++) { - for (int x = startX; x < endingX; x += 2) { - int bit = blockLightArray[x][y][z]; - bit = bit << 4; - bit |= blockLightArray[x + 1][y][z]; - array.add((byte) bit); - } - } - } - subchunks.add(array.toArray(new Byte[2048])); - } - - return subchunks; - } + + private final World world; + private byte[][][] blockLightArray; + + public LightEngineBlock(World world) { + blockLightArray = new byte[world.getChunkWidth() * 16][16 * 18][world.getChunkLength() * 16]; + this.world = world; + updateWorld(); + } + + public void updateWorld() { + blockLightArray = new byte[world.getChunkWidth() * 16][16 * 18][world.getChunkLength() * 16]; + for (int x = 0; x < world.getWidth(); x++) { + for (int y = 0; y < 256; y++) { + for (int z = 0; z < world.getLength(); z++) { + updateBlock(x, y, z); + } + } + } + } + + private void updateBlock(int x, int y, int z) { + BlockState block = world.getBlock(x, y, z); + int lightLevel = getBlockLight(block); + if (lightLevel > 0) { + propergate(lightLevel, x, y, z); + } + } + + private void propergate(int level, int x, int y, int z) { + try { + if (blockLightArray[x][y + 16][z] < level) { + blockLightArray[x][y + 16][z] = (byte) level; + if (level > 1) { + try { + propergate(level - 1, x + 1, y, z); + } catch (ArrayIndexOutOfBoundsException e) { + } + try { + propergate(level - 1, x - 1, y, z); + } catch (ArrayIndexOutOfBoundsException e) { + } + try { + propergate(level - 1, x, y + 1, z); + } catch (ArrayIndexOutOfBoundsException e) { + } + try { + propergate(level - 1, x, y - 1, z); + } catch (ArrayIndexOutOfBoundsException e) { + } + try { + propergate(level - 1, x, y, z + 1); + } catch (ArrayIndexOutOfBoundsException e) { + } + try { + propergate(level - 1, x, y, z - 1); + } catch (ArrayIndexOutOfBoundsException e) { + } + } + } + } catch (ArrayIndexOutOfBoundsException e) { + } + } + + public List getBlockLightBitMask(int chunkX, int chunkZ) { + List subchunks = new ArrayList<>(18); + int startX = chunkX * 16; + int endingX = startX + 16; + int startZ = chunkZ * 16; + int endingZ = startZ + 16; + + for (int sub = 17; sub >= 0; sub--) { + List array = new ArrayList<>(); + for (int y = sub * 16; y < (sub * 16) + 16; y++) { + for (int z = startZ; z < endingZ; z++) { + for (int x = startX; x < endingX; x += 2) { + int bit = blockLightArray[x][y][z]; + bit = bit << 4; + bit |= blockLightArray[x + 1][y][z]; + array.add((byte) bit); + } + } + } + subchunks.add(array.toArray(new Byte[2048])); + } + + return subchunks; + } } diff --git a/src/main/java/com/loohp/limbo/world/LightEngineSky.java b/src/main/java/com/loohp/limbo/world/LightEngineSky.java index bd14fbb..cb4ea7e 100644 --- a/src/main/java/com/loohp/limbo/world/LightEngineSky.java +++ b/src/main/java/com/loohp/limbo/world/LightEngineSky.java @@ -4,12 +4,12 @@ import java.util.ArrayList; import java.util.List; public class LightEngineSky extends LightEngine { - - private World world; - private byte[][][] skyLightArray; - - public LightEngineSky(World world) { - skyLightArray = new byte[world.getChunkWidth() * 16][16 * 18][world.getChunkLength() * 16]; + + private final World world; + private byte[][][] skyLightArray; + + public LightEngineSky(World world) { + skyLightArray = new byte[world.getChunkWidth() * 16][16 * 18][world.getChunkLength() * 16]; /* for (byte[][] arrayarray : skyLightArray) { for (byte[] array : arrayarray) { @@ -17,71 +17,87 @@ public class LightEngineSky extends LightEngine { } } */ - this.world = world; - updateWorld(); - } - - public void updateWorld() { - skyLightArray = new byte[world.getChunkWidth() * 16][16 * 18][world.getChunkLength() * 16]; - for (int x = 0; x < world.getWidth(); x++) { - for (int z = 0; z < world.getLength(); z++) { - updateColumn(x, z); - } - } - } - - private void updateColumn(int x, int z) { - for (int y = 272; y >= 256; y--) { - propergate(15, x, y, z); - } - for (int y = 255; y >= 0; y--) { - BlockState block = world.getBlock(x, y, z); - //System.out.println("X:" + x + " Y: " + y + " Z: " + z + " Block: " + block.getType().toString()); - if (!block.getType().toString().equals("minecraft:air")) { - break; - } - propergate(15, x, y, z); - } - } - - private void propergate(int level, int x, int y, int z) { - try { - if (skyLightArray[x][y + 16][z] < level) { - skyLightArray[x][y + 16][z] = (byte) level; - if (level > 1) { - try {propergate(level - 1, x + 1, y, z);} catch (ArrayIndexOutOfBoundsException e) {} - try {propergate(level - 1, x - 1, y, z);} catch (ArrayIndexOutOfBoundsException e) {} - try {propergate(level - 1, x, y + 1, z);} catch (ArrayIndexOutOfBoundsException e) {} - try {propergate(level - 1, x, y, z + 1);} catch (ArrayIndexOutOfBoundsException e) {} - try {propergate(level - 1, x, y, z - 1);} catch (ArrayIndexOutOfBoundsException e) {} - } - } - } catch (ArrayIndexOutOfBoundsException e) {} - } - - public List getSkyLightBitMask(int chunkX, int chunkZ) { - List subchunks = new ArrayList<>(18); - int startX = chunkX * 16; - int endingX = startX + 16; - int startZ = chunkZ * 16; - int endingZ = startZ + 16; - - for (int sub = 17; sub >= 0; sub--) { - List array = new ArrayList<>(); - for (int y = sub * 16; y < (sub * 16) + 16; y++) { - for (int z = startZ; z < endingZ; z++) { - for (int x = startX; x < endingX; x += 2) { - int bit = skyLightArray[x][y][z]; - bit = bit << 4; - bit |= skyLightArray[x + 1][y][z]; - array.add((byte) bit); - } - } - } - subchunks.add(array.toArray(new Byte[2048])); - } - - return subchunks; - } + this.world = world; + updateWorld(); + } + + public void updateWorld() { + skyLightArray = new byte[world.getChunkWidth() * 16][16 * 18][world.getChunkLength() * 16]; + for (int x = 0; x < world.getWidth(); x++) { + for (int z = 0; z < world.getLength(); z++) { + updateColumn(x, z); + } + } + } + + private void updateColumn(int x, int z) { + for (int y = 272; y >= 256; y--) { + propergate(15, x, y, z); + } + for (int y = 255; y >= 0; y--) { + BlockState block = world.getBlock(x, y, z); + //System.out.println("X:" + x + " Y: " + y + " Z: " + z + " Block: " + block.getType().toString()); + if (!block.getType().toString().equals("minecraft:air")) { + break; + } + propergate(15, x, y, z); + } + } + + private void propergate(int level, int x, int y, int z) { + try { + if (skyLightArray[x][y + 16][z] < level) { + skyLightArray[x][y + 16][z] = (byte) level; + if (level > 1) { + try { + propergate(level - 1, x + 1, y, z); + } catch (ArrayIndexOutOfBoundsException e) { + } + try { + propergate(level - 1, x - 1, y, z); + } catch (ArrayIndexOutOfBoundsException e) { + } + try { + propergate(level - 1, x, y + 1, z); + } catch (ArrayIndexOutOfBoundsException e) { + } + try { + propergate(level - 1, x, y, z + 1); + } catch (ArrayIndexOutOfBoundsException e) { + } + try { + propergate(level - 1, x, y, z - 1); + } catch (ArrayIndexOutOfBoundsException e) { + } + } + } + } catch (ArrayIndexOutOfBoundsException e) { + } + } + + public List getSkyLightBitMask(int chunkX, int chunkZ) { + List subchunks = new ArrayList<>(18); + int startX = chunkX * 16; + int endingX = startX + 16; + int startZ = chunkZ * 16; + int endingZ = startZ + 16; + + for (int sub = 17; sub >= 0; sub--) { + List array = new ArrayList<>(); + for (int y = sub * 16; y < (sub * 16) + 16; y++) { + for (int z = startZ; z < endingZ; z++) { + for (int x = startX; x < endingX; x += 2) { + int bit = skyLightArray[x][y][z]; + bit = bit << 4; + bit |= skyLightArray[x + 1][y][z]; + array.add((byte) bit); + } + } + } + subchunks.add(array.toArray(new Byte[2048])); + } + + return subchunks; + } } diff --git a/src/main/java/com/loohp/limbo/world/Schematic.java b/src/main/java/com/loohp/limbo/world/Schematic.java index 556699b..cee0251 100644 --- a/src/main/java/com/loohp/limbo/world/Schematic.java +++ b/src/main/java/com/loohp/limbo/world/Schematic.java @@ -1,33 +1,32 @@ package com.loohp.limbo.world; +import com.loohp.limbo.utils.SchematicConvertionUtils; +import net.querz.mca.Chunk; +import net.querz.nbt.tag.CompoundTag; +import net.querz.nbt.tag.ListTag; + import java.util.HashMap; import java.util.Iterator; import java.util.Map; -import com.loohp.limbo.utils.SchematicConvertionUtils; - -import net.querz.mca.Chunk; -import net.querz.nbt.tag.CompoundTag; -import net.querz.nbt.tag.ListTag; - public class Schematic { - - public static World toWorld(String name, Environment environment, CompoundTag nbt) { - short width = nbt.getShort("Width"); - short length = nbt.getShort("Length"); - //short height = nbt.getShort("Height"); - byte[] blockdata = nbt.getByteArray("BlockData"); - CompoundTag palette = nbt.getCompoundTag("Palette"); - ListTag blockEntities = nbt.containsKey("BlockEntities") ? nbt.getListTag("BlockEntities").asTypedList(CompoundTag.class) : null; - Map mapping = new HashMap<>(); - for (String key : palette.keySet()) { - mapping.put(palette.getInt(key), key); - } - - World world = new World(name, width, length, environment); - - int index = 0; + + public static World toWorld(String name, Environment environment, CompoundTag nbt) { + short width = nbt.getShort("Width"); + short length = nbt.getShort("Length"); + //short height = nbt.getShort("Height"); + byte[] blockdata = nbt.getByteArray("BlockData"); + CompoundTag palette = nbt.getCompoundTag("Palette"); + ListTag blockEntities = nbt.containsKey("BlockEntities") ? nbt.getListTag("BlockEntities").asTypedList(CompoundTag.class) : null; + Map mapping = new HashMap<>(); + for (String key : palette.keySet()) { + mapping.put(palette.getInt(key), key); + } + + World world = new World(name, width, length, environment); + + int index = 0; int i = 0; int value = 0; int varint_length = 0; @@ -53,43 +52,43 @@ public class Schematic { world.setBlock(x, y, z, mapping.get(value)); Chunk chunk = world.getChunkAtWorldPos(x, z); - + if (blockEntities != null) { - Iterator itr = blockEntities.iterator(); - while (itr.hasNext()) { - CompoundTag tag = itr.next(); - int[] pos = tag.getIntArray("Pos"); - - if (pos[0] == x && pos[1] == y && pos[2] == z) { - ListTag newTag = chunk.getTileEntities(); - newTag.add(SchematicConvertionUtils.toTileEntityTag(tag)); - chunk.setTileEntities(newTag); - itr.remove(); - break; - } - } + Iterator itr = blockEntities.iterator(); + while (itr.hasNext()) { + CompoundTag tag = itr.next(); + int[] pos = tag.getIntArray("Pos"); + + if (pos[0] == x && pos[1] == y && pos[2] == z) { + ListTag newTag = chunk.getTileEntities(); + newTag.add(SchematicConvertionUtils.toTileEntityTag(tag)); + chunk.setTileEntities(newTag); + itr.remove(); + break; + } + } } - + index++; } - - for (Chunk[] chunkarray : world.getChunks()) { - for (Chunk chunk : chunkarray) { - if (chunk != null) { - CompoundTag heightMap = new CompoundTag(); - heightMap.putLongArray("MOTION_BLOCKING", new long[] {1371773531765642314L,1389823183635651148L,1371738278539598925L,1389823183635388492L,1353688558756731469L,1389823114781694027L,1317765589597723213L,1371773531899860042L,1389823183635651149L,1371773462911685197L,1389823183635650636L,1353688626805119565L,1371773531900123211L,1335639250618849869L,1371738278674077258L,1389823114781694028L,1353723811310638154L,1371738278674077259L,1335674228429068364L,1335674228429067338L,1335674228698027594L,1317624576693539402L,1335709481520370249L,1299610178184057417L,1335638906349064264L,1299574993811968586L,1299574924958011464L,1299610178184056904L,1299574924958011464L,1299610109330100296L,1299574924958011464L,1299574924823793736L,1299574924958011465L,1281525273222484040L,1299574924958011464L,1281525273222484040L,9548107335L}); - chunk.setHeightMaps(heightMap); - chunk.setBiomes(new int[256]); - chunk.cleanupPalettesAndBlockStates(); - } - } - } - - world.getLightEngineBlock().updateWorld(); - if (world.hasSkyLight()) { - world.getLightEngineSky().updateWorld(); - } - - return world; - } + + for (Chunk[] chunkarray : world.getChunks()) { + for (Chunk chunk : chunkarray) { + if (chunk != null) { + CompoundTag heightMap = new CompoundTag(); + heightMap.putLongArray("MOTION_BLOCKING", new long[]{1371773531765642314L, 1389823183635651148L, 1371738278539598925L, 1389823183635388492L, 1353688558756731469L, 1389823114781694027L, 1317765589597723213L, 1371773531899860042L, 1389823183635651149L, 1371773462911685197L, 1389823183635650636L, 1353688626805119565L, 1371773531900123211L, 1335639250618849869L, 1371738278674077258L, 1389823114781694028L, 1353723811310638154L, 1371738278674077259L, 1335674228429068364L, 1335674228429067338L, 1335674228698027594L, 1317624576693539402L, 1335709481520370249L, 1299610178184057417L, 1335638906349064264L, 1299574993811968586L, 1299574924958011464L, 1299610178184056904L, 1299574924958011464L, 1299610109330100296L, 1299574924958011464L, 1299574924823793736L, 1299574924958011465L, 1281525273222484040L, 1299574924958011464L, 1281525273222484040L, 9548107335L}); + chunk.setHeightMaps(heightMap); + chunk.setBiomes(new int[256]); + chunk.cleanupPalettesAndBlockStates(); + } + } + } + + world.getLightEngineBlock().updateWorld(); + if (world.hasSkyLight()) { + world.getLightEngineSky().updateWorld(); + } + + return world; + } } \ No newline at end of file diff --git a/src/main/java/com/loohp/limbo/world/Unsafe.java b/src/main/java/com/loohp/limbo/world/Unsafe.java index 56e176c..bd0a6dd 100644 --- a/src/main/java/com/loohp/limbo/world/Unsafe.java +++ b/src/main/java/com/loohp/limbo/world/Unsafe.java @@ -5,17 +5,18 @@ import com.loohp.limbo.entity.Entity; @Deprecated public class Unsafe { - - private Unsafe() {} - - @Deprecated - public void a(World a, Entity b) { - a.removeEntity(b); - } - - @Deprecated - public DataWatcher b(World a, Entity b) { - return a.getDataWatcher(b); - } - + + private Unsafe() { + } + + @Deprecated + public void a(World a, Entity b) { + a.removeEntity(b); + } + + @Deprecated + public DataWatcher b(World a, Entity b) { + return a.getDataWatcher(b); + } + } diff --git a/src/main/java/com/loohp/limbo/world/World.java b/src/main/java/com/loohp/limbo/world/World.java index d891099..6eec824 100644 --- a/src/main/java/com/loohp/limbo/world/World.java +++ b/src/main/java/com/loohp/limbo/world/World.java @@ -1,311 +1,300 @@ package com.loohp.limbo.world; -import java.io.IOException; -import java.lang.reflect.Field; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - import com.loohp.limbo.Limbo; -import com.loohp.limbo.server.packets.PacketPlayOutEntityDestroy; -import com.loohp.limbo.server.packets.PacketPlayOutEntityMetadata; import com.loohp.limbo.entity.ArmorStand; import com.loohp.limbo.entity.DataWatcher; +import com.loohp.limbo.entity.DataWatcher.WatchableObject; import com.loohp.limbo.entity.Entity; import com.loohp.limbo.entity.EntityType; -import com.loohp.limbo.entity.DataWatcher.WatchableObject; import com.loohp.limbo.location.Location; import com.loohp.limbo.player.Player; +import com.loohp.limbo.server.packets.PacketPlayOutEntityDestroy; +import com.loohp.limbo.server.packets.PacketPlayOutEntityMetadata; import com.loohp.limbo.utils.SchematicConvertionUtils; - import net.querz.mca.Chunk; import net.querz.nbt.tag.CompoundTag; import net.querz.nbt.tag.ListTag; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.*; +import java.util.stream.Collectors; + public class World { - private String name; - private Environment environment; - private Chunk[][] chunks; - private int width; - private int length; - private LightEngineBlock lightEngineBlock; - private LightEngineSky lightEngineSky; - private Map entities; + private final String name; + private final Environment environment; + private final Chunk[][] chunks; + private final int width; + private final int length; + private final LightEngineBlock lightEngineBlock; + private LightEngineSky lightEngineSky; + private final Map entities; - public World(String name, int width, int length, Environment environment) { - this.name = name; - this.environment = environment; - this.chunks = new Chunk[(width >> 4) + 1][(length >> 4) + 1]; - this.width = width; - this.length = length; + public World(String name, int width, int length, Environment environment) { + this.name = name; + this.environment = environment; + this.chunks = new Chunk[(width >> 4) + 1][(length >> 4) + 1]; + this.width = width; + this.length = length; - for (int x = 0; x < chunks.length; x++) { - for (int z = 0; z < chunks[x].length; z++) { - chunks[x][z] = Chunk.newChunk(); - Chunk chunk = chunks[x][z]; - chunk.cleanupPalettesAndBlockStates(); - CompoundTag heightMap = new CompoundTag(); - heightMap.putLongArray("MOTION_BLOCKING", - new long[] {1371773531765642314L, 1389823183635651148L, 1371738278539598925L, - 1389823183635388492L, 1353688558756731469L, 1389823114781694027L, 1317765589597723213L, - 1371773531899860042L, 1389823183635651149L, 1371773462911685197L, 1389823183635650636L, - 1353688626805119565L, 1371773531900123211L, 1335639250618849869L, 1371738278674077258L, - 1389823114781694028L, 1353723811310638154L, 1371738278674077259L, 1335674228429068364L, - 1335674228429067338L, 1335674228698027594L, 1317624576693539402L, 1335709481520370249L, - 1299610178184057417L, 1335638906349064264L, 1299574993811968586L, 1299574924958011464L, - 1299610178184056904L, 1299574924958011464L, 1299610109330100296L, 1299574924958011464L, - 1299574924823793736L, 1299574924958011465L, 1281525273222484040L, 1299574924958011464L, - 1281525273222484040L, 9548107335L}); - chunk.setHeightMaps(heightMap); - chunk.setBiomes(new int[256]); - chunk.setTileEntities(new ListTag(CompoundTag.class)); - } - } - - this.lightEngineBlock = new LightEngineBlock(this); - if (environment.hasSkyLight()) { - this.lightEngineSky = new LightEngineSky(this); - } - - this.entities = new LinkedHashMap<>(); - } + for (int x = 0; x < chunks.length; x++) { + for (int z = 0; z < chunks[x].length; z++) { + chunks[x][z] = Chunk.newChunk(); + Chunk chunk = chunks[x][z]; + chunk.cleanupPalettesAndBlockStates(); + CompoundTag heightMap = new CompoundTag(); + heightMap.putLongArray("MOTION_BLOCKING", + new long[]{1371773531765642314L, 1389823183635651148L, 1371738278539598925L, + 1389823183635388492L, 1353688558756731469L, 1389823114781694027L, 1317765589597723213L, + 1371773531899860042L, 1389823183635651149L, 1371773462911685197L, 1389823183635650636L, + 1353688626805119565L, 1371773531900123211L, 1335639250618849869L, 1371738278674077258L, + 1389823114781694028L, 1353723811310638154L, 1371738278674077259L, 1335674228429068364L, + 1335674228429067338L, 1335674228698027594L, 1317624576693539402L, 1335709481520370249L, + 1299610178184057417L, 1335638906349064264L, 1299574993811968586L, 1299574924958011464L, + 1299610178184056904L, 1299574924958011464L, 1299610109330100296L, 1299574924958011464L, + 1299574924823793736L, 1299574924958011465L, 1281525273222484040L, 1299574924958011464L, + 1281525273222484040L, 9548107335L}); + chunk.setHeightMaps(heightMap); + chunk.setBiomes(new int[256]); + chunk.setTileEntities(new ListTag(CompoundTag.class)); + } + } - public LightEngineBlock getLightEngineBlock() { - return lightEngineBlock; - } - - public LightEngineSky getLightEngineSky() { - return lightEngineSky; - } - - public boolean hasSkyLight() { - return lightEngineSky != null; - } + this.lightEngineBlock = new LightEngineBlock(this); + if (environment.hasSkyLight()) { + this.lightEngineSky = new LightEngineSky(this); + } - protected void setBlock(int x, int y, int z, String blockdata) { - Chunk chunk = this.chunks[(x >> 4)][(z >> 4)]; - if (chunk == null) { - chunk = Chunk.newChunk(); - this.chunks[(x >> 4)][(z >> 4)] = chunk; - } - CompoundTag block = SchematicConvertionUtils.toBlockTag(blockdata); - chunk.setBlockStateAt(x, y, z, block, false); - } - - public BlockState getBlock(int x, int y, int z) { - Chunk chunk = this.chunks[(x >> 4)][(z >> 4)]; - if (chunk == null) { - chunk = Chunk.newChunk(); - this.chunks[(x >> 4)][(z >> 4)] = chunk; - } - - CompoundTag tag = chunk.getBlockStateAt(x, y, z); - if (tag == null) { - tag = new CompoundTag(); - tag.putString("Name", "minecraft:air"); - } - return new BlockState(tag); - } - - public void setBlock(int x, int y, int z, BlockState state) { - Chunk chunk = this.chunks[(x >> 4)][(z >> 4)]; - if (chunk == null) { - chunk = Chunk.newChunk(); - this.chunks[(x >> 4)][(z >> 4)] = chunk; - } - chunk.setBlockStateAt(x % 16, y % 16, z % 16, state.toCompoundTag(), false); - } + this.entities = new LinkedHashMap<>(); + } - public Chunk[][] getChunks() { - return this.chunks; - } + public LightEngineBlock getLightEngineBlock() { + return lightEngineBlock; + } - public Chunk getChunkAtWorldPos(int x, int z) { - return this.chunks[(x >> 4)][(z >> 4)]; - } - - public Chunk getChunkAt(int x, int z) { - if (x < 0 || z < 0 || x >= chunks.length || z >= chunks[x].length) { - return null; - } - return this.chunks[x][z]; - } - - public int getChunkX(Chunk chunk) { - for (int x = 0; x < chunks.length; x++) { - for (int z = 0; z < chunks[x].length; z++) { - Chunk c = getChunkAt(x, z); - if (c.equals(chunk)) { - return x; - } - } - } - return Integer.MIN_VALUE; - } - - public int getChunkZ(Chunk chunk) { - for (int x = 0; x < chunks.length; x++) { - for (int z = 0; z < chunks[x].length; z++) { - Chunk c = getChunkAt(x, z); - if (c.equals(chunk)) { - return z; - } - } - } - return Integer.MIN_VALUE; - } - - public int[] getChunkXZ(Chunk chunk) { - for (int x = 0; x < chunks.length; x++) { - for (int z = 0; z < chunks[x].length; z++) { - Chunk c = getChunkAt(x, z); - if (c.equals(chunk)) { - return new int[] {x, z}; - } - } - } - return null; - } + public LightEngineSky getLightEngineSky() { + return lightEngineSky; + } - public String getName() { - return name; - } + public boolean hasSkyLight() { + return lightEngineSky != null; + } - public Environment getEnvironment() { - return environment; - } - - public int getWidth() { - return width; - } + protected void setBlock(int x, int y, int z, String blockdata) { + Chunk chunk = this.chunks[(x >> 4)][(z >> 4)]; + if (chunk == null) { + chunk = Chunk.newChunk(); + this.chunks[(x >> 4)][(z >> 4)] = chunk; + } + CompoundTag block = SchematicConvertionUtils.toBlockTag(blockdata); + chunk.setBlockStateAt(x, y, z, block, false); + } - public int getLength() { - return length; - } - - public int getChunkWidth() { - return (width >> 4) + 1; - } + public BlockState getBlock(int x, int y, int z) { + Chunk chunk = this.chunks[(x >> 4)][(z >> 4)]; + if (chunk == null) { + chunk = Chunk.newChunk(); + this.chunks[(x >> 4)][(z >> 4)] = chunk; + } - public int getChunkLength() { - return (length >> 4) + 1; - } - - public Set getEntities() { - return Collections.unmodifiableSet(entities.keySet()); - } - - public Entity spawnEntity(EntityType type, Location location) { - if (!location.getWorld().equals(this)) { - throw new IllegalArgumentException("Location not in world."); - } - Entity entity; - switch (type) { - case ARMOR_STAND: - entity = new ArmorStand(location); - break; - default: - throw new UnsupportedOperationException("This EntityType cannot be summoned."); - } - entities.put(entity, new DataWatcher(entity)); - return entity; - } - - public Entity addEntity(Entity entity) { - if (entity.getWorld().equals(this)) { - entities.put(entity, new DataWatcher(entity)); - } else { - throw new IllegalArgumentException("Location not in world."); - } - return entity; - } - - public List getPlayers() { - return Limbo.getInstance().getPlayers().stream().filter(each -> each.getWorld().equals(this)).collect(Collectors.toList()); - } - - protected void removeEntity(Entity entity) { - entities.remove(entity); - PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(entity.getEntityId()); - for (Player player : getPlayers()) { - try { - player.clientConnection.sendPacket(packet); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - protected DataWatcher getDataWatcher(Entity entity) { - return entities.get(entity); - } - - public void update() throws IllegalArgumentException, IllegalAccessException { - for (DataWatcher watcher : entities.values()) { - if (watcher.getEntity().getWorld().equals(this)) { - Map updated = watcher.update(); - PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(watcher.getEntity(), false, updated.keySet().toArray(new Field[0])); - for (Player player : getPlayers()) { - try { - player.clientConnection.sendPacket(packet); - } catch (IOException e) { - e.printStackTrace(); - } - } - } else { - PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(watcher.getEntity().getEntityId()); - for (Player player : getPlayers()) { - try { - player.clientConnection.sendPacket(packet); - } catch (IOException e) { - e.printStackTrace(); - } - } - entities.remove(watcher.getEntity()); - } - } - } + CompoundTag tag = chunk.getBlockStateAt(x, y, z); + if (tag == null) { + tag = new CompoundTag(); + tag.putString("Name", "minecraft:air"); + } + return new BlockState(tag); + } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + Arrays.deepHashCode(chunks); - result = prime * result + ((environment == null) ? 0 : environment.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - return result; - } + public void setBlock(int x, int y, int z, BlockState state) { + Chunk chunk = this.chunks[(x >> 4)][(z >> 4)]; + if (chunk == null) { + chunk = Chunk.newChunk(); + this.chunks[(x >> 4)][(z >> 4)] = chunk; + } + chunk.setBlockStateAt(x % 16, y % 16, z % 16, state.toCompoundTag(), false); + } - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - World other = (World) obj; - if (!Arrays.deepEquals(chunks, other.chunks)) { - return false; - } - if (environment != other.environment) { - return false; - } - if (name == null) { - if (other.name != null) { - return false; - } - } else if (!name.equals(other.name)) { - return false; - } - return true; - } + public Chunk[][] getChunks() { + return this.chunks; + } + + public Chunk getChunkAtWorldPos(int x, int z) { + return this.chunks[(x >> 4)][(z >> 4)]; + } + + public Chunk getChunkAt(int x, int z) { + if (x < 0 || z < 0 || x >= chunks.length || z >= chunks[x].length) { + return null; + } + return this.chunks[x][z]; + } + + public int getChunkX(Chunk chunk) { + for (int x = 0; x < chunks.length; x++) { + for (int z = 0; z < chunks[x].length; z++) { + Chunk c = getChunkAt(x, z); + if (c.equals(chunk)) { + return x; + } + } + } + return Integer.MIN_VALUE; + } + + public int getChunkZ(Chunk chunk) { + for (int x = 0; x < chunks.length; x++) { + for (int z = 0; z < chunks[x].length; z++) { + Chunk c = getChunkAt(x, z); + if (c.equals(chunk)) { + return z; + } + } + } + return Integer.MIN_VALUE; + } + + public int[] getChunkXZ(Chunk chunk) { + for (int x = 0; x < chunks.length; x++) { + for (int z = 0; z < chunks[x].length; z++) { + Chunk c = getChunkAt(x, z); + if (c.equals(chunk)) { + return new int[]{x, z}; + } + } + } + return null; + } + + public String getName() { + return name; + } + + public Environment getEnvironment() { + return environment; + } + + public int getWidth() { + return width; + } + + public int getLength() { + return length; + } + + public int getChunkWidth() { + return (width >> 4) + 1; + } + + public int getChunkLength() { + return (length >> 4) + 1; + } + + public Set getEntities() { + return Collections.unmodifiableSet(entities.keySet()); + } + + public Entity spawnEntity(EntityType type, Location location) { + if (!location.getWorld().equals(this)) { + throw new IllegalArgumentException("Location not in world."); + } + Entity entity; + switch (type) { + case ARMOR_STAND: + entity = new ArmorStand(location); + break; + default: + throw new UnsupportedOperationException("This EntityType cannot be summoned."); + } + entities.put(entity, new DataWatcher(entity)); + return entity; + } + + public Entity addEntity(Entity entity) { + if (entity.getWorld().equals(this)) { + entities.put(entity, new DataWatcher(entity)); + } else { + throw new IllegalArgumentException("Location not in world."); + } + return entity; + } + + public List getPlayers() { + return Limbo.getInstance().getPlayers().stream().filter(each -> each.getWorld().equals(this)).collect(Collectors.toList()); + } + + protected void removeEntity(Entity entity) { + entities.remove(entity); + PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(entity.getEntityId()); + for (Player player : getPlayers()) { + try { + player.clientConnection.sendPacket(packet); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + protected DataWatcher getDataWatcher(Entity entity) { + return entities.get(entity); + } + + public void update() throws IllegalArgumentException, IllegalAccessException { + for (DataWatcher watcher : entities.values()) { + if (watcher.getEntity().getWorld().equals(this)) { + Map updated = watcher.update(); + PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(watcher.getEntity(), false, updated.keySet().toArray(new Field[0])); + for (Player player : getPlayers()) { + try { + player.clientConnection.sendPacket(packet); + } catch (IOException e) { + e.printStackTrace(); + } + } + } else { + PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(watcher.getEntity().getEntityId()); + for (Player player : getPlayers()) { + try { + player.clientConnection.sendPacket(packet); + } catch (IOException e) { + e.printStackTrace(); + } + } + entities.remove(watcher.getEntity()); + } + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + Arrays.deepHashCode(chunks); + result = prime * result + ((environment == null) ? 0 : environment.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + World other = (World) obj; + if (!Arrays.deepEquals(chunks, other.chunks)) { + return false; + } + if (environment != other.environment) { + return false; + } + if (name == null) { + return other.name == null; + } else return name.equals(other.name); + } }