Let intellij reformat the code

This commit is contained in:
Alex 2021-04-16 10:29:54 +02:00
parent 3ccfca9ecf
commit 87aaf7f7b3
115 changed files with 8024 additions and 8227 deletions

View File

@ -1,193 +1,34 @@
package com.loohp.limbo; 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.commands.CommandSender;
import com.loohp.limbo.consolegui.ConsoleTextOutput; import com.loohp.limbo.consolegui.ConsoleTextOutput;
import com.loohp.limbo.utils.CustomStringUtils; import com.loohp.limbo.utils.CustomStringUtils;
import jline.console.ConsoleReader; import jline.console.ConsoleReader;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent; 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 { public class Console implements CommandSender {
protected static final Map<ChatColor, String> REPLACEMENTS = new HashMap<>(); protected static final Map<ChatColor, String> REPLACEMENTS = new HashMap<>();
private final static String CONSOLE = "CONSOLE"; protected final static String ERROR_RED = "\u001B[31;1m";
private final static String PROMPT = "> "; protected final static String RESET_COLOR = "\u001B[0m";
protected final static String ERROR_RED = "\u001B[31;1m"; private final static String CONSOLE = "CONSOLE";
protected final static String RESET_COLOR = "\u001B[0m"; private final static String PROMPT = "> ";
private Terminal terminal; static {
private LineReader tabReader; REPLACEMENTS.put(ChatColor.BLACK, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLACK).boldOff().toString());
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<Candidate> candidates) {
String[] args = CustomStringUtils.splitStringToArgs(line.line());
List<String> 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 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());
REPLACEMENTS.put(ChatColor.DARK_BLUE, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLUE).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_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()); 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.UNDERLINE, Ansi.ansi().a(Attribute.UNDERLINE).toString());
REPLACEMENTS.put(ChatColor.ITALIC, Ansi.ansi().a(Attribute.ITALIC).toString()); REPLACEMENTS.put(ChatColor.ITALIC, Ansi.ansi().a(Attribute.ITALIC).toString());
REPLACEMENTS.put(ChatColor.RESET, Ansi.ansi().a(Attribute.RESET).toString()); REPLACEMENTS.put(ChatColor.RESET, Ansi.ansi().a(Attribute.RESET).toString());
} }
protected static String translateToConsole(String str) { protected PrintStream logs;
for (Entry<ChatColor, String> entry : REPLACEMENTS.entrySet()) { private final Terminal terminal;
str = str.replace(entry.getKey().toString(), entry.getValue()); private final LineReader tabReader;
} private final ConsoleReader reader;
str = str.replaceAll("(?i)" + ChatColor.COLOR_CHAR + "x(" + ChatColor.COLOR_CHAR + "[0-9a-f]){6}", ""); private final InputStream in;
return str + RESET_COLOR; @SuppressWarnings("unused")
} private final PrintStream out;
@SuppressWarnings("unused")
private final PrintStream err;
public static class ConsoleOutputStream extends PrintStream { 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);
private PrintStream logs; if (in != null) {
private Console console; 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;
public ConsoleOutputStream(Console console, OutputStream out, PrintStream logs) { System.setErr(new ConsoleErrorStream(this, err == null ? new PrintStream(new OutputStream() {
super(out); @Override
this.logs = logs; public void write(int b) {
this.console = console; //DO NOTHING
} }
}) : err, this.logs));
this.err = System.err;
@SuppressWarnings("resource") reader = new ConsoleReader(in, out);
@Override reader.setExpandEvents(false);
public PrintStream printf(Locale l, String format, Object... args) { reader.setHandleUserInterrupt(false);
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;
}
@SuppressWarnings("resource") terminal = TerminalBuilder.builder().streams(in, out).system(true).jansi(true).build();
@Override tabReader = LineReaderBuilder.builder().terminal(terminal).completer(new Completer() {
public PrintStream printf(String format, Object... args) { @Override
console.stashLine(); public void complete(LineReader reader, ParsedLine line, List<Candidate> candidates) {
String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); String[] args = CustomStringUtils.splitStringToArgs(line.line());
ConsoleTextOutput.appendText(ChatColor.stripColor(String.format("[" + date + " Info]" + format, args))); List<String> tab = Limbo.getInstance().getPluginManager().getTabOptions(Limbo.getInstance().getConsole(), args);
logs.printf(ChatColor.stripColor("[" + date + " Info]" + format), args); for (String each : tab) {
PrintStream stream = super.printf(ChatColor.stripColor("[" + date + " Info]" + format), args); candidates.add(new Candidate(each));
console.unstashLine(); }
return stream; }
} }).build();
tabReader.setAutosuggestion(SuggestionType.NONE);
}
@Override protected static String translateToConsole(String str) {
public void println() { for (Entry<ChatColor, String> entry : REPLACEMENTS.entrySet()) {
console.stashLine(); str = str.replace(entry.getKey().toString(), entry.getValue());
String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); }
ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info]"), true); str = str.replaceAll("(?i)" + ChatColor.COLOR_CHAR + "x(" + ChatColor.COLOR_CHAR + "[0-9a-f]){6}", "");
logs.println(ChatColor.stripColor("[" + date + " Info]")); return str + RESET_COLOR;
super.println(ChatColor.stripColor("[" + date + " Info]")); }
console.unstashLine();
}
@Override @Override
public void println(boolean x) { public String getName() {
console.stashLine(); return CONSOLE;
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 @Override
public void println(char x) { public boolean hasPermission(String permission) {
console.stashLine(); return Limbo.getInstance().getPermissionsManager().hasPermission(this, permission);
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 @Override
public void println(char[] x) { public void sendMessage(BaseComponent component, UUID uuid) {
console.stashLine(); sendMessage(component);
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 @Override
public void println(double x) { public void sendMessage(BaseComponent[] component, UUID uuid) {
console.stashLine(); sendMessage(component);
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 @Override
public void println(float x) { public void sendMessage(String message, UUID uuid) {
console.stashLine(); sendMessage(message);
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 @Override
public void println(int x) { public void sendMessage(BaseComponent component) {
console.stashLine(); sendMessage(new BaseComponent[]{component});
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 @Override
public void println(long x) { public void sendMessage(BaseComponent[] component) {
console.stashLine(); sendMessage(String.join("", Arrays.asList(component).stream().map(each -> each.toLegacyText()).collect(Collectors.toList())));
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 @Override
public void println(Object x) { public void sendMessage(String message) {
console.stashLine(); stashLine();
String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date());
ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + x), true); ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + message), true);
logs.println(ChatColor.stripColor("[" + date + " Info]" + x)); logs.println(ChatColor.stripColor("[" + date + " Info] " + message));
super.println(ChatColor.stripColor("[" + date + " Info]" + x)); try {
console.unstashLine(); reader.getOutput().append("[" + date + " Info] " + translateToConsole(message) + "\n");
} reader.getOutput().flush();
} catch (IOException e) {
e.printStackTrace();
}
unstashLine();
}
@Override protected void run() {
public void println(String string) { if (in == null) {
console.stashLine(); return;
String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); }
ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + string), true); while (true) {
logs.println(ChatColor.stripColor("[" + date + " Info] " + string)); try {
super.println(ChatColor.stripColor("[" + date + " Info] " + string)); String command = tabReader.readLine(PROMPT).trim();
console.unstashLine(); 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;
}
}
}
public static class ConsoleErrorStream extends PrintStream { protected void stashLine() {
try {
tabReader.callWidget(LineReader.CLEAR);
} catch (Exception ignore) {
}
}
private PrintStream logs; protected void unstashLine() {
private Console console; try {
tabReader.callWidget(LineReader.REDRAW_LINE);
tabReader.callWidget(LineReader.REDISPLAY);
tabReader.getTerminal().writer().flush();
} catch (Exception ignore) {
}
}
public ConsoleErrorStream(Console console, OutputStream out, PrintStream logs) { public static class ConsoleOutputStream extends PrintStream {
super(out);
this.logs = logs;
this.console = console;
}
@SuppressWarnings("resource") private final PrintStream logs;
@Override private final Console console;
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") public ConsoleOutputStream(Console console, OutputStream out, PrintStream logs) {
@Override super(out);
public PrintStream printf(String format, Object... args) { this.logs = logs;
console.stashLine(); this.console = console;
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 @SuppressWarnings("resource")
public void println() { @Override
console.stashLine(); public PrintStream printf(Locale l, String format, Object... args) {
String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); console.stashLine();
ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error]"), true); String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date());
logs.println(ChatColor.stripColor("[" + date + " Error]")); ConsoleTextOutput.appendText(ChatColor.stripColor(String.format(l, "[" + date + " Info]" + format, args)));
super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]") + RESET_COLOR); logs.printf(l, ChatColor.stripColor("[" + date + " Info]" + format), args);
console.unstashLine(); PrintStream stream = super.printf(l, Console.translateToConsole("[" + date + " Info]" + format), args);
} console.unstashLine();
return stream;
}
@Override @SuppressWarnings("resource")
public void println(boolean x) { @Override
console.stashLine(); public PrintStream printf(String format, Object... args) {
String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); console.stashLine();
ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + x), true); String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date());
logs.println(ChatColor.stripColor("[" + date + " Error]" + x)); ConsoleTextOutput.appendText(ChatColor.stripColor(String.format("[" + date + " Info]" + format, args)));
super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + x) + RESET_COLOR); logs.printf(ChatColor.stripColor("[" + date + " Info]" + format), args);
console.unstashLine(); PrintStream stream = super.printf(ChatColor.stripColor("[" + date + " Info]" + format), args);
} console.unstashLine();
return stream;
}
@Override @Override
public void println(char x) { public void println() {
console.stashLine(); console.stashLine();
String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date());
ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + x), true); ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info]"), true);
logs.println(ChatColor.stripColor("[" + date + " Error]" + x)); logs.println(ChatColor.stripColor("[" + date + " Info]"));
super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + x) + RESET_COLOR); super.println(ChatColor.stripColor("[" + date + " Info]"));
console.unstashLine(); console.unstashLine();
} }
@Override @Override
public void println(char[] x) { public void println(boolean x) {
console.stashLine(); console.stashLine();
String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date());
ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + String.valueOf(x)), true); ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + x), true);
logs.println(ChatColor.stripColor("[" + date + " Error]" + String.valueOf(x))); logs.println(ChatColor.stripColor("[" + date + " Info]" + x));
super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + String.valueOf(x)) + RESET_COLOR); super.println(ChatColor.stripColor("[" + date + " Info]" + x));
console.unstashLine(); console.unstashLine();
} }
@Override @Override
public void println(double x) { public void println(char x) {
console.stashLine(); console.stashLine();
String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date());
ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + x), true); ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + x), true);
logs.println(ChatColor.stripColor("[" + date + " Error]" + x)); logs.println(ChatColor.stripColor("[" + date + " Info]" + x));
super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + x) + RESET_COLOR); super.println(ChatColor.stripColor("[" + date + " Info]" + x));
console.unstashLine(); console.unstashLine();
} }
@Override @Override
public void println(float x) { public void println(char[] x) {
console.stashLine(); console.stashLine();
String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date());
ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + x), true); ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + String.valueOf(x)), true);
logs.println(ChatColor.stripColor("[" + date + " Error]" + x)); logs.println(ChatColor.stripColor("[" + date + " Info]" + String.valueOf(x)));
super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + x) + RESET_COLOR); super.println(ChatColor.stripColor("[" + date + " Info]" + String.valueOf(x)));
console.unstashLine(); console.unstashLine();
} }
@Override @Override
public void println(int x) { public void println(double x) {
console.stashLine(); console.stashLine();
String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date());
ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + x), true); ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + x), true);
logs.println(ChatColor.stripColor("[" + date + " Error]" + x)); logs.println(ChatColor.stripColor("[" + date + " Info]" + x));
super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + x) + RESET_COLOR); super.println(ChatColor.stripColor("[" + date + " Info]" + x));
console.unstashLine(); console.unstashLine();
} }
@Override @Override
public void println(long x) { public void println(float x) {
console.stashLine(); console.stashLine();
String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date());
ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + x), true); ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + x), true);
logs.println(ChatColor.stripColor("[" + date + " Error]" + x)); logs.println(ChatColor.stripColor("[" + date + " Info]" + x));
super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + x) + RESET_COLOR); super.println(ChatColor.stripColor("[" + date + " Info]" + x));
console.unstashLine(); console.unstashLine();
} }
@Override @Override
public void println(Object x) { public void println(int x) {
console.stashLine(); console.stashLine();
String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date());
ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + x), true); ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + x), true);
logs.println(ChatColor.stripColor("[" + date + " Error]" + x)); logs.println(ChatColor.stripColor("[" + date + " Info]" + x));
super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error]" + x) + RESET_COLOR); super.println(ChatColor.stripColor("[" + date + " Info]" + x));
console.unstashLine(); console.unstashLine();
} }
@Override @Override
public void println(String string) { public void println(long x) {
console.stashLine(); console.stashLine();
String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date()); String date = new SimpleDateFormat("HH':'mm':'ss").format(new Date());
ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Error] " + string), true); ConsoleTextOutput.appendText(ChatColor.stripColor("[" + date + " Info] " + x), true);
logs.println(ChatColor.stripColor("[" + date + " Error] " + string)); logs.println(ChatColor.stripColor("[" + date + " Info]" + x));
super.println(ERROR_RED + ChatColor.stripColor("[" + date + " Error] " + string) + RESET_COLOR); super.println(ChatColor.stripColor("[" + date + " Info]" + x));
console.unstashLine(); 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();
}
}
} }

View File

@ -1,51 +1,10 @@
package com.loohp.limbo; 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.Gson;
import com.google.gson.GsonBuilder; 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.commands.CommandSender;
import com.loohp.limbo.consolegui.GUI; import com.loohp.limbo.consolegui.GUI;
import com.loohp.limbo.events.EventsManager;
import com.loohp.limbo.file.ServerProperties; import com.loohp.limbo.file.ServerProperties;
import com.loohp.limbo.location.Location; import com.loohp.limbo.location.Location;
import com.loohp.limbo.metrics.Metrics; 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.plugins.PluginManager;
import com.loohp.limbo.scheduler.LimboScheduler; import com.loohp.limbo.scheduler.LimboScheduler;
import com.loohp.limbo.scheduler.Tick; 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.CustomStringUtils;
import com.loohp.limbo.utils.ImageUtils; import com.loohp.limbo.utils.ImageUtils;
import com.loohp.limbo.utils.NetworkUtils; import com.loohp.limbo.utils.NetworkUtils;
@ -62,132 +25,107 @@ import com.loohp.limbo.world.DimensionRegistry;
import com.loohp.limbo.world.Environment; import com.loohp.limbo.world.Environment;
import com.loohp.limbo.world.Schematic; import com.loohp.limbo.world.Schematic;
import com.loohp.limbo.world.World; import com.loohp.limbo.world.World;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.chat.ComponentSerializer; import net.md_5.bungee.chat.ComponentSerializer;
import net.querz.nbt.io.NBTUtil; import net.querz.nbt.io.NBTUtil;
import net.querz.nbt.tag.CompoundTag; 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 { public class Limbo {
private static Limbo instance; public static boolean noGui = false;
public static boolean noGui = false; private static Limbo instance;
public final String serverImplementationVersion = "1.16.5";
public final int serverImplmentationProtocol = 754;
public static void main(String args[]) throws IOException, ParseException, NumberFormatException, ClassNotFoundException, InterruptedException { //===========================
for (String flag : args) { public final String limboImplementationVersion;
if (flag.equals("--nogui") || flag.equals("nogui")) { public AtomicInteger entityIdCount = new AtomicInteger();
noGui = true; private final AtomicBoolean isRunning;
} else if (flag.equals("--help")) { private final ServerConnection server;
System.out.println("Accepted flags:"); private final Console console;
System.out.println(" --nogui <- Disable the GUI"); private final List<World> worlds = new ArrayList<>();
System.exit(0); private final Map<String, Player> playersByName = new HashMap<>();
} else { private final Map<UUID, Player> playersByUUID = new HashMap<>();
System.out.println("Unknown flag: \"" + flag + "\". Ignoring..."); private final ServerProperties properties;
} private final PluginManager pluginManager;
} private final EventsManager eventsManager;
if (GraphicsEnvironment.isHeadless()) { private final PermissionsManager permissionManager;
noGui = true; private final File pluginFolder;
} private final File internalDataFolder;
if (!noGui) { private final DimensionRegistry dimensionRegistry;
System.out.println("Launching Server GUI.. Add \"--nogui\" in launch arguments to disable"); private final Tick tick;
Thread t1 = new Thread(new Runnable() { private final LimboScheduler scheduler;
@Override private final Metrics metrics;
public void run() { @SuppressWarnings("deprecation")
GUI.main(); private final Unsafe unsafe = new Unsafe();
}
});
t1.start();
}
new Limbo(); @SuppressWarnings("unchecked")
} public Limbo() throws IOException, ParseException, NumberFormatException, ClassNotFoundException, InterruptedException {
instance = this;
isRunning = new AtomicBoolean(true);
public static Limbo getInstance() { if (!noGui) {
return instance; 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);
public final String serverImplementationVersion = "1.16.5"; String spName = "server.properties";
public final int serverImplmentationProtocol = 754;
public final String limboImplementationVersion;
private AtomicBoolean isRunning;
private ServerConnection server;
private Console console;
private List<World> worlds = new ArrayList<>();
private Map<String, Player> playersByName = new HashMap<>();
private Map<UUID, Player> 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";
File sp = new File(spName); File sp = new File(spName);
if (!sp.exists()) { if (!sp.exists()) {
try (InputStream in = getClass().getClassLoader().getResourceAsStream(spName)) { try (InputStream in = getClass().getClassLoader().getResourceAsStream(spName)) {
Files.copy(in, sp.toPath()); Files.copy(in, sp.toPath());
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
properties = new ServerProperties(sp); properties = new ServerProperties(sp);
if (!properties.isBungeecord()) { 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 { } else {
console.sendMessage("Starting Limbo server in bungeecord mode!"); console.sendMessage("Starting Limbo server in bungeecord mode!");
} }
internalDataFolder = new File("internal_data"); internalDataFolder = new File("internal_data");
if (!internalDataFolder.exists()) { if (!internalDataFolder.exists()) {
internalDataFolder.mkdirs(); internalDataFolder.mkdirs();
} }
String mappingName = "mapping.json"; String mappingName = "mapping.json";
File mappingFile = new File(internalDataFolder, mappingName); File mappingFile = new File(internalDataFolder, mappingName);
if (!mappingFile.exists()) { if (!mappingFile.exists()) {
try (InputStream in = getClass().getClassLoader().getResourceAsStream(mappingName)) { try (InputStream in = getClass().getClassLoader().getResourceAsStream(mappingName)) {
Files.copy(in, mappingFile.toPath()); Files.copy(in, mappingFile.toPath());
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@ -200,91 +138,91 @@ public class Limbo {
String classPrefix = Packet.class.getName().substring(0, Packet.class.getName().lastIndexOf(".") + 1); String classPrefix = Packet.class.getName().substring(0, Packet.class.getName().lastIndexOf(".") + 1);
int mappingsCount = 0; int mappingsCount = 0;
Map<Integer, Class<? extends PacketIn>> HandshakeIn = new HashMap<>(); Map<Integer, Class<? extends PacketIn>> HandshakeIn = new HashMap<>();
for (Object key : ((JSONObject) json.get("HandshakeIn")).keySet()) { for (Object key : ((JSONObject) json.get("HandshakeIn")).keySet()) {
int packetId = Integer.decode((String) key); int packetId = Integer.decode((String) key);
HandshakeIn.put(packetId, (Class<? extends PacketIn>) Class.forName(classPrefix + (String) ((JSONObject) json.get("HandshakeIn")).get(key))); HandshakeIn.put(packetId, (Class<? extends PacketIn>) Class.forName(classPrefix + ((JSONObject) json.get("HandshakeIn")).get(key)));
} }
Packet.setHandshakeIn(HandshakeIn); Packet.setHandshakeIn(HandshakeIn);
mappingsCount += HandshakeIn.size(); mappingsCount += HandshakeIn.size();
Map<Integer, Class<? extends PacketIn>> StatusIn = new HashMap<>(); Map<Integer, Class<? extends PacketIn>> StatusIn = new HashMap<>();
for (Object key : ((JSONObject) json.get("StatusIn")).keySet()) { for (Object key : ((JSONObject) json.get("StatusIn")).keySet()) {
int packetId = Integer.decode((String) key); int packetId = Integer.decode((String) key);
StatusIn.put(packetId, (Class<? extends PacketIn>) Class.forName(classPrefix + (String) ((JSONObject) json.get("StatusIn")).get(key))); StatusIn.put(packetId, (Class<? extends PacketIn>) Class.forName(classPrefix + ((JSONObject) json.get("StatusIn")).get(key)));
} }
Packet.setStatusIn(StatusIn); Packet.setStatusIn(StatusIn);
mappingsCount += StatusIn.size(); mappingsCount += StatusIn.size();
Map<Class<? extends PacketOut>, Integer> StatusOut = new HashMap<>(); Map<Class<? extends PacketOut>, Integer> StatusOut = new HashMap<>();
for (Object key : ((JSONObject) json.get("StatusOut")).keySet()) { for (Object key : ((JSONObject) json.get("StatusOut")).keySet()) {
Class<? extends PacketOut> packetClass = (Class<? extends PacketOut>) Class.forName(classPrefix + (String) key); Class<? extends PacketOut> packetClass = (Class<? extends PacketOut>) Class.forName(classPrefix + key);
StatusOut.put(packetClass, Integer.decode((String) ((JSONObject) json.get("StatusOut")).get(key))); StatusOut.put(packetClass, Integer.decode((String) ((JSONObject) json.get("StatusOut")).get(key)));
} }
Packet.setStatusOut(StatusOut); Packet.setStatusOut(StatusOut);
mappingsCount += StatusOut.size(); mappingsCount += StatusOut.size();
Map<Integer, Class<? extends PacketIn>> LoginIn = new HashMap<>(); Map<Integer, Class<? extends PacketIn>> LoginIn = new HashMap<>();
for (Object key : ((JSONObject) json.get("LoginIn")).keySet()) { for (Object key : ((JSONObject) json.get("LoginIn")).keySet()) {
int packetId = Integer.decode((String) key); int packetId = Integer.decode((String) key);
LoginIn.put(packetId, (Class<? extends PacketIn>) Class.forName(classPrefix + (String) ((JSONObject) json.get("LoginIn")).get(key))); LoginIn.put(packetId, (Class<? extends PacketIn>) Class.forName(classPrefix + ((JSONObject) json.get("LoginIn")).get(key)));
} }
Packet.setLoginIn(LoginIn); Packet.setLoginIn(LoginIn);
mappingsCount += LoginIn.size(); mappingsCount += LoginIn.size();
Map<Class<? extends PacketOut>, Integer> LoginOut = new HashMap<>(); Map<Class<? extends PacketOut>, Integer> LoginOut = new HashMap<>();
for (Object key : ((JSONObject) json.get("LoginOut")).keySet()) { for (Object key : ((JSONObject) json.get("LoginOut")).keySet()) {
Class<? extends PacketOut> packetClass = (Class<? extends PacketOut>) Class.forName(classPrefix + (String) key); Class<? extends PacketOut> packetClass = (Class<? extends PacketOut>) Class.forName(classPrefix + key);
LoginOut.put(packetClass, Integer.decode((String) ((JSONObject) json.get("LoginOut")).get(key))); LoginOut.put(packetClass, Integer.decode((String) ((JSONObject) json.get("LoginOut")).get(key)));
} }
Packet.setLoginOut(LoginOut); Packet.setLoginOut(LoginOut);
mappingsCount += LoginOut.size(); mappingsCount += LoginOut.size();
Map<Integer, Class<? extends PacketIn>> PlayIn = new HashMap<>(); Map<Integer, Class<? extends PacketIn>> PlayIn = new HashMap<>();
for (Object key : ((JSONObject) json.get("PlayIn")).keySet()) { for (Object key : ((JSONObject) json.get("PlayIn")).keySet()) {
int packetId = Integer.decode((String) key); int packetId = Integer.decode((String) key);
PlayIn.put(packetId, (Class<? extends PacketIn>) Class.forName(classPrefix + (String) ((JSONObject) json.get("PlayIn")).get(key))); PlayIn.put(packetId, (Class<? extends PacketIn>) Class.forName(classPrefix + ((JSONObject) json.get("PlayIn")).get(key)));
} }
Packet.setPlayIn(PlayIn); Packet.setPlayIn(PlayIn);
mappingsCount += PlayIn.size(); mappingsCount += PlayIn.size();
Map<Class<? extends PacketOut>, Integer> PlayOut = new HashMap<>(); Map<Class<? extends PacketOut>, Integer> PlayOut = new HashMap<>();
for (Object key : ((JSONObject) json.get("PlayOut")).keySet()) { for (Object key : ((JSONObject) json.get("PlayOut")).keySet()) {
Class<? extends PacketOut> packetClass = (Class<? extends PacketOut>) Class.forName(classPrefix + (String) key); Class<? extends PacketOut> packetClass = (Class<? extends PacketOut>) Class.forName(classPrefix + key);
PlayOut.put(packetClass, Integer.decode((String) ((JSONObject) json.get("PlayOut")).get(key))); PlayOut.put(packetClass, Integer.decode((String) ((JSONObject) json.get("PlayOut")).get(key)));
} }
Packet.setPlayOut(PlayOut); Packet.setPlayOut(PlayOut);
mappingsCount += PlayOut.size(); mappingsCount += PlayOut.size();
console.sendMessage("Loaded all " + mappingsCount + " packet id mappings!"); console.sendMessage("Loaded all " + mappingsCount + " packet id mappings!");
dimensionRegistry = new DimensionRegistry(); dimensionRegistry = new DimensionRegistry();
worlds.add(loadDefaultWorld()); worlds.add(loadDefaultWorld());
Location spawn = properties.getWorldSpawn(); Location spawn = properties.getWorldSpawn();
properties.setWorldSpawn(new Location(getWorld(properties.getLevelName().getKey()), spawn.getX(), spawn.getY(), spawn.getZ(), spawn.getYaw(), spawn.getPitch())); properties.setWorldSpawn(new Location(getWorld(properties.getLevelName().getKey()), spawn.getX(), spawn.getY(), spawn.getZ(), spawn.getYaw(), spawn.getPitch()));
if (!NetworkUtils.available(properties.getServerPort())) { if (!NetworkUtils.available(properties.getServerPort())) {
console.sendMessage(""); console.sendMessage("");
console.sendMessage("*****FAILED TO BIND PORT [" + properties.getServerPort() + "]*****"); console.sendMessage("*****FAILED TO BIND PORT [" + properties.getServerPort() + "]*****");
console.sendMessage("*****PORT ALREADY IN USE*****"); console.sendMessage("*****PORT ALREADY IN USE*****");
console.sendMessage("*****PERHAPS ANOTHER INSTANCE OF THE SERVER IS ALREADY RUNNING?*****"); console.sendMessage("*****PERHAPS ANOTHER INSTANCE OF THE SERVER IS ALREADY RUNNING?*****");
console.sendMessage(""); console.sendMessage("");
System.exit(2); System.exit(2);
} }
String permissionName = "permission.yml"; String permissionName = "permission.yml";
File permissionFile = new File(permissionName); File permissionFile = new File(permissionName);
if (!permissionFile.exists()) { if (!permissionFile.exists()) {
try (InputStream in = getClass().getClassLoader().getResourceAsStream(permissionName)) { try (InputStream in = getClass().getClassLoader().getResourceAsStream(permissionName)) {
Files.copy(in, permissionFile.toPath()); Files.copy(in, permissionFile.toPath());
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
scheduler = new LimboScheduler(); scheduler = new LimboScheduler();
tick = new Tick(this); tick = new Tick(this);
permissionManager = new PermissionsManager(); permissionManager = new PermissionsManager();
permissionManager.loadDefaultPermissionFile(permissionFile); permissionManager.loadDefaultPermissionFile(permissionFile);
@ -298,280 +236,313 @@ public class Limbo {
defaultCommandsJar.delete(); defaultCommandsJar.delete();
console.sendMessage("Downloading limbo default commands module from github..."); 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()); ReadableByteChannel rbc = Channels.newChannel(new URL("https://github.com/LOOHP/Limbo/raw/master/modules/LimboDefaultCmd.jar").openStream());
FileOutputStream fos = new FileOutputStream(defaultCommandsJar); FileOutputStream fos = new FileOutputStream(defaultCommandsJar);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close(); fos.close();
pluginManager = new PluginManager(pluginFolder); pluginManager = new PluginManager(pluginFolder);
try { try {
Method loadPluginsMethod = PluginManager.class.getDeclaredMethod("loadPlugins"); Method loadPluginsMethod = PluginManager.class.getDeclaredMethod("loadPlugins");
loadPluginsMethod.setAccessible(true); loadPluginsMethod.setAccessible(true);
loadPluginsMethod.invoke(pluginManager); loadPluginsMethod.invoke(pluginManager);
loadPluginsMethod.setAccessible(false); loadPluginsMethod.setAccessible(false);
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace(); e.printStackTrace();
} }
for (LimboPlugin plugin : Limbo.getInstance().getPluginManager().getPlugins()) { for (LimboPlugin plugin : Limbo.getInstance().getPluginManager().getPlugins()) {
console.sendMessage("Enabling plugin " + plugin.getName() + " " + plugin.getInfo().getVersion()); console.sendMessage("Enabling plugin " + plugin.getName() + " " + plugin.getInfo().getVersion());
plugin.onEnable(); plugin.onEnable();
} }
server = new ServerConnection(properties.getServerIp(), properties.getServerPort()); server = new ServerConnection(properties.getServerIp(), properties.getServerPort());
metrics = new Metrics(); metrics = new Metrics();
Runtime.getRuntime().addShutdownHook(new Thread(() -> { Runtime.getRuntime().addShutdownHook(new Thread(() -> {
Limbo.getInstance().terminate(); Limbo.getInstance().terminate();
})); }));
console.run(); console.run();
} }
@Deprecated public static void main(String[] args) throws IOException, ParseException, NumberFormatException, ClassNotFoundException, InterruptedException {
public Unsafe getUnsafe() { for (String flag : args) {
return unsafe; 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 Tick getHeartBeat() { new Limbo();
return tick; }
}
public LimboScheduler getScheduler() { public static Limbo getInstance() {
return scheduler; return instance;
} }
public DimensionRegistry getDimensionRegistry() { @Deprecated
return dimensionRegistry; public Unsafe getUnsafe() {
} return unsafe;
}
public PermissionsManager getPermissionsManager() { public Tick getHeartBeat() {
return permissionManager; return tick;
} }
public File getInternalDataFolder() { public LimboScheduler getScheduler() {
return internalDataFolder; return scheduler;
} }
public EventsManager getEventsManager() { public DimensionRegistry getDimensionRegistry() {
return eventsManager; return dimensionRegistry;
} }
public File getPluginFolder() { public PermissionsManager getPermissionsManager() {
return pluginFolder; return permissionManager;
} }
public PluginManager getPluginManager() { public File getInternalDataFolder() {
return pluginManager; return internalDataFolder;
} }
private World loadDefaultWorld() throws IOException { public EventsManager getEventsManager() {
console.sendMessage("Loading world " + properties.getLevelName() + " with the schematic file " + properties.getSchemFileName() + " ..."); return eventsManager;
}
File schem = new File(properties.getSchemFileName()); public File getPluginFolder() {
return pluginFolder;
}
if (!schem.exists()) { public PluginManager getPluginManager() {
console.sendMessage("Schemetic file " + properties.getSchemFileName() + " for world " + properties.getLevelName() + " not found!"); return pluginManager;
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()); private World loadDefaultWorld() throws IOException {
console.sendMessage("Loading world " + properties.getLevelName() + " with the schematic file " + properties.getSchemFileName() + " ...");
console.sendMessage("Loaded world " + properties.getLevelName() + "!"); File schem = new File(properties.getSchemFileName());
return world; 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;
}
public void registerWorld(World world) { World world = Schematic.toWorld(properties.getLevelName().getKey(), Environment.fromNamespacedKey(properties.getLevelDimension()), (CompoundTag) NBTUtil.read(schem).getTag());
if (!worlds.contains(world)) {
worlds.add(world);
} else {
throw new RuntimeException("World already registered");
}
}
public void unregisterWorld(World world) { console.sendMessage("Loaded world " + properties.getLevelName() + "!");
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 world;
return properties; }
}
public ServerConnection getServerConnection() { public void registerWorld(World world) {
return server; if (!worlds.contains(world)) {
} worlds.add(world);
} else {
throw new RuntimeException("World already registered");
}
}
public Console getConsole() { public void unregisterWorld(World world) {
return console; 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 Metrics getMetrics() { public ServerProperties getServerProperties() {
return metrics; return properties;
} }
public Set<Player> getPlayers() { public ServerConnection getServerConnection() {
return new HashSet<>(playersByUUID.values()); return server;
} }
public Player getPlayer(String name) { public Console getConsole() {
return playersByName.get(name); return console;
} }
public Player getPlayer(UUID uuid) { public Metrics getMetrics() {
return playersByUUID.get(uuid); return metrics;
} }
public void addPlayer(Player player) { public Set<Player> getPlayers() {
playersByName.put(player.getName(), player); return new HashSet<>(playersByUUID.values());
playersByUUID.put(player.getUniqueId(), player); }
}
public void removePlayer(Player player) { public Player getPlayer(String name) {
playersByName.remove(player.getName()); return playersByName.get(name);
playersByUUID.remove(player.getUniqueId()); }
}
public List<World> getWorlds() { public Player getPlayer(UUID uuid) {
return new ArrayList<>(worlds); return playersByUUID.get(uuid);
} }
public World getWorld(String name) { public void addPlayer(Player player) {
for (World world : worlds) { playersByName.put(player.getName(), player);
if (world.getName().equalsIgnoreCase(name)) { playersByUUID.put(player.getUniqueId(), player);
return world; }
}
}
return null;
}
@SuppressWarnings("unchecked") public void removePlayer(Player player) {
public String buildServerListResponseJson(String version, int protocol, BaseComponent[] motd, int maxPlayers, int playersOnline, BufferedImage favicon) throws IOException { playersByName.remove(player.getName());
JSONObject json = new JSONObject(); playersByUUID.remove(player.getUniqueId());
}
JSONObject versionJson = new JSONObject(); public List<World> getWorlds() {
versionJson.put("name", version); return new ArrayList<>(worlds);
versionJson.put("protocol", protocol); }
json.put("version", versionJson);
JSONObject playersJson = new JSONObject(); public World getWorld(String name) {
playersJson.put("max", maxPlayers); for (World world : worlds) {
playersJson.put("online", playersOnline); if (world.getName().equalsIgnoreCase(name)) {
json.put("players", playersJson); return world;
}
}
return null;
}
json.put("description", "%MOTD%"); @SuppressWarnings("unchecked")
public String buildServerListResponseJson(String version, int protocol, BaseComponent[] motd, int maxPlayers, int playersOnline, BufferedImage favicon) throws IOException {
JSONObject json = new JSONObject();
if (favicon != null) { JSONObject versionJson = new JSONObject();
if (favicon.getWidth() == 64 && favicon.getHeight() == 64) { versionJson.put("name", version);
String base64 = "data:image/png;base64," + ImageUtils.imgToBase64String(favicon, "png"); versionJson.put("protocol", protocol);
json.put("favicon", base64); json.put("version", versionJson);
} else {
console.sendMessage("Server List Favicon must be 64 x 64 in size!");
}
}
JSONObject modInfoJson = new JSONObject(); JSONObject playersJson = new JSONObject();
modInfoJson.put("type", "FML"); playersJson.put("max", maxPlayers);
modInfoJson.put("modList", new JSONArray()); playersJson.put("online", playersOnline);
json.put("modinfo", modInfoJson); 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<String, Object> treeMap = new TreeMap<String, Object>(String.CASE_INSENSITIVE_ORDER); TreeMap<String, Object> treeMap = new TreeMap<String, Object>(String.CASE_INSENSITIVE_ORDER);
treeMap.putAll(json); treeMap.putAll(json);
Gson g = new GsonBuilder().create(); Gson g = new GsonBuilder().create();
return g.toJson(treeMap).replace("\"%MOTD%\"", ComponentSerializer.toString(motd)); return g.toJson(treeMap).replace("\"%MOTD%\"", ComponentSerializer.toString(motd));
} }
public String buildLegacyPingResponse(String version, BaseComponent[] motd, int maxPlayers, int playersOnline) { public String buildLegacyPingResponse(String version, BaseComponent[] motd, int maxPlayers, int playersOnline) {
String begin = "§1"; String begin = "<EFBFBD>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)); 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() { protected void terminate() {
isRunning.set(false); isRunning.set(false);
console.sendMessage("Stopping Server..."); console.sendMessage("Stopping Server...");
for (LimboPlugin plugin : Limbo.getInstance().getPluginManager().getPlugins()) { for (LimboPlugin plugin : Limbo.getInstance().getPluginManager().getPlugins()) {
console.sendMessage("Disabling plugin " + plugin.getName() + " " + plugin.getInfo().getVersion()); console.sendMessage("Disabling plugin " + plugin.getName() + " " + plugin.getInfo().getVersion());
plugin.onDisable(); plugin.onDisable();
} }
tick.waitAndKillThreads(5000); tick.waitAndKillThreads(5000);
for (Player player : getPlayers()) { for (Player player : getPlayers()) {
player.disconnect("Server closed"); player.disconnect("Server closed");
} }
while (!getPlayers().isEmpty()) { while (!getPlayers().isEmpty()) {
try { try {
TimeUnit.MILLISECONDS.sleep(500); TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
console.sendMessage("Server closed"); console.sendMessage("Server closed");
console.logs.close(); console.logs.close();
} }
public void stopServer() { public void stopServer() {
System.exit(0); System.exit(0);
} }
public boolean isRunning() { public boolean isRunning() {
return isRunning.get(); return isRunning.get();
} }
public int getNextEntityId() { public int getNextEntityId() {
if (entityIdCount.get() == Integer.MAX_VALUE) { if (entityIdCount.get() == Integer.MAX_VALUE) {
return entityIdCount.getAndSet(0); return entityIdCount.getAndSet(0);
} else { } else {
return entityIdCount.getAndIncrement(); return entityIdCount.getAndIncrement();
} }
} }
public void dispatchCommand(CommandSender sender, String str) { public void dispatchCommand(CommandSender sender, String str) {
String[] command; String[] command;
if (str.startsWith("/")) { if (str.startsWith("/")) {
command = CustomStringUtils.splitStringToArgs(str.substring(1)); command = CustomStringUtils.splitStringToArgs(str.substring(1));
} else { } else {
command = CustomStringUtils.splitStringToArgs(str); command = CustomStringUtils.splitStringToArgs(str);
} }
dispatchCommand(sender, command); dispatchCommand(sender, command);
} }
public void dispatchCommand(CommandSender sender, String... args) { public void dispatchCommand(CommandSender sender, String... args) {
try { try {
Limbo.getInstance().getPluginManager().fireExecutors(sender, args); Limbo.getInstance().getPluginManager().fireExecutors(sender, args);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
private String getLimboVersion() throws IOException { private String getLimboVersion() throws IOException {
Enumeration<URL> manifests = getClass().getClassLoader().getResources("META-INF/MANIFEST.MF"); Enumeration<URL> manifests = getClass().getClassLoader().getResources("META-INF/MANIFEST.MF");
while (manifests.hasMoreElements()) { while (manifests.hasMoreElements()) {
URL url = manifests.nextElement(); URL url = manifests.nextElement();
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream())); BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
Optional<String> line = br.lines().filter(each -> each.startsWith("Limbo-Version:")).findFirst(); Optional<String> line = br.lines().filter(each -> each.startsWith("Limbo-Version:")).findFirst();
br.close(); br.close();
if (line.isPresent()) { if (line.isPresent()) {
return line.get().substring(14).trim(); return line.get().substring(14).trim();
} }
} }
return "Unknown"; return "Unknown";
} }
} }

View File

@ -1,7 +1,5 @@
package com.loohp.limbo; package com.loohp.limbo;
import java.lang.reflect.Constructor;
import com.loohp.limbo.entity.DataWatcher; import com.loohp.limbo.entity.DataWatcher;
import com.loohp.limbo.entity.Entity; import com.loohp.limbo.entity.Entity;
import com.loohp.limbo.location.Location; 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.utils.GameMode;
import com.loohp.limbo.world.World; import com.loohp.limbo.world.World;
import java.lang.reflect.Constructor;
@Deprecated @Deprecated
public class Unsafe { public class Unsafe {
private com.loohp.limbo.player.Unsafe playerUnsafe; private com.loohp.limbo.player.Unsafe playerUnsafe;
private com.loohp.limbo.world.Unsafe worldUnsafe; private com.loohp.limbo.world.Unsafe worldUnsafe;
protected Unsafe() { protected Unsafe() {
try { try {
Constructor<com.loohp.limbo.player.Unsafe> playerConstructor = com.loohp.limbo.player.Unsafe.class.getDeclaredConstructor(); Constructor<com.loohp.limbo.player.Unsafe> playerConstructor = com.loohp.limbo.player.Unsafe.class.getDeclaredConstructor();
playerConstructor.setAccessible(true); playerConstructor.setAccessible(true);
playerUnsafe = playerConstructor.newInstance(); playerUnsafe = playerConstructor.newInstance();
playerConstructor.setAccessible(false); playerConstructor.setAccessible(false);
Constructor<com.loohp.limbo.world.Unsafe> worldConstructor = com.loohp.limbo.world.Unsafe.class.getDeclaredConstructor(); Constructor<com.loohp.limbo.world.Unsafe> worldConstructor = com.loohp.limbo.world.Unsafe.class.getDeclaredConstructor();
worldConstructor.setAccessible(true); worldConstructor.setAccessible(true);
worldUnsafe = worldConstructor.newInstance(); worldUnsafe = worldConstructor.newInstance();
worldConstructor.setAccessible(false); worldConstructor.setAccessible(false);
} catch (Exception e) {e.printStackTrace();} } catch (Exception e) {
} e.printStackTrace();
}
}
@Deprecated @Deprecated
public void setPlayerGameModeSilently(Player player, GameMode mode) { public void setPlayerGameModeSilently(Player player, GameMode mode) {
playerUnsafe.a(player, mode); playerUnsafe.a(player, mode);
} }
@Deprecated @Deprecated
public void setSelectedSlotSilently(Player player, byte slot) { public void setSelectedSlotSilently(Player player, byte slot) {
playerUnsafe.a(player, slot); playerUnsafe.a(player, slot);
} }
@Deprecated @Deprecated
public void setPlayerEntityId(Player player, int entityId) { public void setPlayerEntityId(Player player, int entityId) {
playerUnsafe.a(player, entityId); playerUnsafe.a(player, entityId);
} }
@Deprecated @Deprecated
public void removeEntity(World world, Entity entity) { public void removeEntity(World world, Entity entity) {
worldUnsafe.a(world, entity); worldUnsafe.a(world, entity);
} }
@Deprecated @Deprecated
public DataWatcher getDataWatcher(World world, Entity entity) { public DataWatcher getDataWatcher(World world, Entity entity) {
return worldUnsafe.b(world, entity); return worldUnsafe.b(world, entity);
} }
@Deprecated @Deprecated
public void setPlayerLocationSilently(Player player, Location location) { public void setPlayerLocationSilently(Player player, Location location) {
playerUnsafe.a(player, location); playerUnsafe.a(player, location);
} }
} }

View File

@ -2,6 +2,6 @@ package com.loohp.limbo.commands;
public interface CommandExecutor { public interface CommandExecutor {
public void execute(CommandSender sender, String[] args); void execute(CommandSender sender, String[] args);
} }

View File

@ -1,25 +1,25 @@
package com.loohp.limbo.commands; package com.loohp.limbo.commands;
import java.util.UUID;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
import java.util.UUID;
public interface CommandSender { public interface CommandSender {
public void sendMessage(BaseComponent[] component, UUID uuid); void sendMessage(BaseComponent[] component, UUID uuid);
public void sendMessage(BaseComponent component, UUID uuid); void sendMessage(BaseComponent component, UUID uuid);
public void sendMessage(String message, UUID uuid); void sendMessage(String message, UUID uuid);
public void sendMessage(BaseComponent[] component); void sendMessage(BaseComponent[] component);
public void sendMessage(BaseComponent component); void sendMessage(BaseComponent component);
public void sendMessage(String message); void sendMessage(String message);
public boolean hasPermission(String permission); boolean hasPermission(String permission);
public String getName(); String getName();
} }

View File

@ -4,6 +4,6 @@ import java.util.List;
public interface TabCompletor { public interface TabCompletor {
public List<String> tabComplete(CommandSender sender, String[] args); List<String> tabComplete(CommandSender sender, String[] args);
} }

View File

@ -4,19 +4,19 @@ import com.loohp.limbo.Limbo;
public class ConsoleTextOutput { public class ConsoleTextOutput {
public static void appendText(String string) { public static void appendText(String string) {
if (!Limbo.noGui) { if (!Limbo.noGui) {
GUI.textOutput.setText(GUI.textOutput.getText() + string); GUI.textOutput.setText(GUI.textOutput.getText() + string);
GUI.scrollPane.getVerticalScrollBar().setValue(GUI.scrollPane.getVerticalScrollBar().getMaximum()); GUI.scrollPane.getVerticalScrollBar().setValue(GUI.scrollPane.getVerticalScrollBar().getMaximum());
} }
} }
public static void appendText(String string, boolean isWriteLine) { public static void appendText(String string, boolean isWriteLine) {
if (isWriteLine) { if (isWriteLine) {
appendText(string + "\n"); appendText(string + "\n");
} else { } else {
appendText(string); appendText(string);
} }
} }
} }

View File

@ -1,220 +1,205 @@
package com.loohp.limbo.consolegui; package com.loohp.limbo.consolegui;
import java.awt.Font; import com.loohp.limbo.Limbo;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout; import javax.swing.*;
import java.awt.Insets; import javax.swing.border.EmptyBorder;
import java.awt.event.KeyAdapter; import java.awt.*;
import java.awt.event.KeyEvent; import java.awt.event.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; 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") @SuppressWarnings("serial")
public class GUI extends JFrame { public class GUI extends JFrame {
public static JPanel contentPane; public static JPanel contentPane;
public static JTextField commandInput; public static JTextField commandInput;
public static JButton execCommand; public static JButton execCommand;
public static JTextPane textOutput; public static JTextPane textOutput;
public static JScrollPane scrollPane; public static JScrollPane scrollPane;
public static JLabel consoleLabel; public static JLabel consoleLabel;
public static JLabel clientLabel; public static JLabel clientLabel;
public static JTextPane clientText; public static JTextPane clientText;
public static JScrollPane scrollPane_client; public static JScrollPane scrollPane_client;
public static JLabel sysLabel; public static JLabel sysLabel;
public static JScrollPane scrollPane_sys; public static JScrollPane scrollPane_sys;
public static JTextPane sysText; public static JTextPane sysText;
public static List<String> history = new ArrayList<String>(); public static List<String> history = new ArrayList<String>();
public static int currenthistory = 0; public static int currenthistory = 0;
public static boolean loadFinish = false; public static boolean loadFinish = false;
/** /**
* Launch the application. * Create the frame.
*/ */
public static void main() { public GUI() {
GUI frame = new GUI(); setTitle("Limbo Minecraft Server");
frame.setVisible(true); 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);
Thread t1 = new Thread(new Runnable() { sysLabel = new JLabel("System Information");
@Override sysLabel.setFont(new Font("Arial", Font.BOLD, 11));
public void run() { GridBagConstraints gbc_sysLabel = new GridBagConstraints();
SystemInfo.printInfo(); gbc_sysLabel.fill = GridBagConstraints.BOTH;
} gbc_sysLabel.insets = new Insets(0, 0, 5, 5);
}); gbc_sysLabel.gridx = 0;
t1.start(); gbc_sysLabel.gridy = 0;
contentPane.add(sysLabel, gbc_sysLabel);
loadFinish = true; 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();
* Create the frame. commandInput.setToolTipText("Input a command");
*/ commandInput.addKeyListener(new KeyAdapter() {
public GUI() { @Override
setTitle("Limbo Minecraft Server"); public void keyPressed(KeyEvent e) {
addWindowListener(new WindowAdapter() { if (e.getKeyCode() == 10) {
@Override String cmd = commandInput.getText();
public void windowClosing(WindowEvent e) { if (!commandInput.getText().equals("")) {
if (Limbo.getInstance().isRunning()) { history.add(cmd);
Limbo.getInstance().stopServer(); currenthistory = history.size();
} }
} Limbo.getInstance().dispatchCommand(Limbo.getInstance().getConsole(), cmd.trim().replaceAll(" +", " "));
}); commandInput.setText("");
setBounds(100, 100, 1198, 686); } else if (e.getKeyCode() == 38) {
contentPane = new JPanel(); currenthistory--;
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); if (currenthistory >= 0) {
setContentPane(contentPane); commandInput.setText(history.get(currenthistory));
GridBagLayout gbl_contentPane = new GridBagLayout(); } else {
gbl_contentPane.columnWidths = new int[]{243, 10, 36, 111, 0}; currenthistory++;
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}; } else if (e.getKeyCode() == 40) {
gbl_contentPane.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 1.0, 0.0, Double.MIN_VALUE}; currenthistory++;
contentPane.setLayout(gbl_contentPane); if (currenthistory < history.size()) {
commandInput.setText(history.get(currenthistory));
} else {
currenthistory--;
}
}
}
});
sysLabel = new JLabel("System Information"); scrollPane_sys = new JScrollPane();
sysLabel.setFont(new Font("Arial", Font.BOLD, 11)); GridBagConstraints gbc_scrollPane_sys = new GridBagConstraints();
GridBagConstraints gbc_sysLabel = new GridBagConstraints(); gbc_scrollPane_sys.insets = new Insets(0, 0, 5, 5);
gbc_sysLabel.fill = GridBagConstraints.BOTH; gbc_scrollPane_sys.fill = GridBagConstraints.BOTH;
gbc_sysLabel.insets = new Insets(0, 0, 5, 5); gbc_scrollPane_sys.gridx = 0;
gbc_sysLabel.gridx = 0; gbc_scrollPane_sys.gridy = 1;
gbc_sysLabel.gridy = 0; contentPane.add(scrollPane_sys, gbc_scrollPane_sys);
contentPane.add(sysLabel, gbc_sysLabel);
consoleLabel = new JLabel("Console Output"); sysText = new JTextPane();
consoleLabel.setFont(new Font("Arial", Font.BOLD, 11)); sysText.setFont(new Font("Consolas", Font.PLAIN, 12));
GridBagConstraints gbc_consoleLabel = new GridBagConstraints(); sysText.setEditable(false);
gbc_consoleLabel.anchor = GridBagConstraints.WEST; scrollPane_sys.setViewportView(sysText);
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(); clientLabel = new JLabel("Connected Clients");
commandInput.setToolTipText("Input a command"); clientLabel.setFont(new Font("Arial", Font.BOLD, 11));
commandInput.addKeyListener(new KeyAdapter() { GridBagConstraints gbc_clientLabel = new GridBagConstraints();
@Override gbc_clientLabel.anchor = GridBagConstraints.WEST;
public void keyPressed(KeyEvent e) { gbc_clientLabel.insets = new Insets(0, 0, 5, 5);
if (e.getKeyCode() == 10) { gbc_clientLabel.gridx = 0;
String cmd = commandInput.getText(); gbc_clientLabel.gridy = 3;
if (!commandInput.getText().equals("")) { contentPane.add(clientLabel, gbc_clientLabel);
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(); scrollPane_client = new JScrollPane();
GridBagConstraints gbc_scrollPane_sys = new GridBagConstraints(); GridBagConstraints gbc_scrollPane_client = new GridBagConstraints();
gbc_scrollPane_sys.insets = new Insets(0, 0, 5, 5); gbc_scrollPane_client.fill = GridBagConstraints.BOTH;
gbc_scrollPane_sys.fill = GridBagConstraints.BOTH; gbc_scrollPane_client.gridheight = 2;
gbc_scrollPane_sys.gridx = 0; gbc_scrollPane_client.insets = new Insets(0, 0, 0, 5);
gbc_scrollPane_sys.gridy = 1; gbc_scrollPane_client.gridx = 0;
contentPane.add(scrollPane_sys, gbc_scrollPane_sys); gbc_scrollPane_client.gridy = 4;
contentPane.add(scrollPane_client, gbc_scrollPane_client);
sysText = new JTextPane(); clientText = new JTextPane();
sysText.setFont(new Font("Consolas", Font.PLAIN, 12)); scrollPane_client.setViewportView(clientText);
sysText.setEditable(false); clientText.setFont(new Font("Consolas", Font.PLAIN, 12));
scrollPane_sys.setViewportView(sysText); clientText.setEditable(false);
clientLabel = new JLabel("Connected Clients"); scrollPane = new JScrollPane();
clientLabel.setFont(new Font("Arial", Font.BOLD, 11)); GridBagConstraints gbc_scrollPane = new GridBagConstraints();
GridBagConstraints gbc_clientLabel = new GridBagConstraints(); gbc_scrollPane.gridheight = 4;
gbc_clientLabel.anchor = GridBagConstraints.WEST; gbc_scrollPane.insets = new Insets(0, 0, 5, 0);
gbc_clientLabel.insets = new Insets(0, 0, 5, 5); gbc_scrollPane.gridwidth = 2;
gbc_clientLabel.gridx = 0; gbc_scrollPane.fill = GridBagConstraints.BOTH;
gbc_clientLabel.gridy = 3; gbc_scrollPane.gridx = 2;
contentPane.add(clientLabel, gbc_clientLabel); gbc_scrollPane.gridy = 1;
contentPane.add(scrollPane, gbc_scrollPane);
scrollPane_client = new JScrollPane(); textOutput = new JTextPane();
GridBagConstraints gbc_scrollPane_client = new GridBagConstraints(); scrollPane.setViewportView(textOutput);
gbc_scrollPane_client.fill = GridBagConstraints.BOTH; textOutput.setFont(new Font("Consolas", Font.PLAIN, 12));
gbc_scrollPane_client.gridheight = 2; textOutput.setEditable(false);
gbc_scrollPane_client.insets = new Insets(0, 0, 0, 5); commandInput.setFont(new Font("Tahoma", Font.PLAIN, 19));
gbc_scrollPane_client.gridx = 0; GridBagConstraints gbc_commandInput = new GridBagConstraints();
gbc_scrollPane_client.gridy = 4; gbc_commandInput.insets = new Insets(0, 0, 0, 5);
contentPane.add(scrollPane_client, gbc_scrollPane_client); gbc_commandInput.fill = GridBagConstraints.BOTH;
gbc_commandInput.gridx = 2;
gbc_commandInput.gridy = 5;
contentPane.add(commandInput, gbc_commandInput);
commandInput.setColumns(10);
clientText = new JTextPane(); execCommand = new JButton("RUN");
scrollPane_client.setViewportView(clientText); execCommand.setToolTipText("Execute a command");
clientText.setFont(new Font("Consolas", Font.PLAIN, 12)); execCommand.addMouseListener(new MouseAdapter() {
clientText.setEditable(false); @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);
}
scrollPane = new JScrollPane(); /**
GridBagConstraints gbc_scrollPane = new GridBagConstraints(); * Launch the application.
gbc_scrollPane.gridheight = 4; */
gbc_scrollPane.insets = new Insets(0, 0, 5, 0); public static void main() {
gbc_scrollPane.gridwidth = 2; GUI frame = new GUI();
gbc_scrollPane.fill = GridBagConstraints.BOTH; frame.setVisible(true);
gbc_scrollPane.gridx = 2;
gbc_scrollPane.gridy = 1;
contentPane.add(scrollPane, gbc_scrollPane);
textOutput = new JTextPane(); Thread t1 = new Thread(new Runnable() {
scrollPane.setViewportView(textOutput); @Override
textOutput.setFont(new Font("Consolas", Font.PLAIN, 12)); public void run() {
textOutput.setEditable(false); SystemInfo.printInfo();
commandInput.setFont(new Font("Tahoma", Font.PLAIN, 19)); }
GridBagConstraints gbc_commandInput = new GridBagConstraints(); });
gbc_commandInput.insets = new Insets(0, 0, 0, 5); t1.start();
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"); loadFinish = true;
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);
}
} }

View File

@ -1,49 +1,53 @@
package com.loohp.limbo.consolegui; package com.loohp.limbo.consolegui;
import com.loohp.limbo.Limbo;
import java.lang.management.ManagementFactory; import java.lang.management.ManagementFactory;
import java.text.NumberFormat; import java.text.NumberFormat;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import com.loohp.limbo.Limbo;
public class SystemInfo { public class SystemInfo {
public static void printInfo() { public static void printInfo() {
if (!Limbo.noGui) { if (!Limbo.noGui) {
while (true) { while (true) {
Runtime runtime = Runtime.getRuntime(); Runtime runtime = Runtime.getRuntime();
NumberFormat format = NumberFormat.getInstance(); NumberFormat format = NumberFormat.getInstance();
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
long maxMemory = runtime.maxMemory(); long maxMemory = runtime.maxMemory();
long allocatedMemory = runtime.totalMemory(); long allocatedMemory = runtime.totalMemory();
long freeMemory = runtime.freeMemory(); long freeMemory = runtime.freeMemory();
sb.append("Free Memory: " + format.format(freeMemory / 1024 / 1024) + " MB\n"); sb.append("Free Memory: " + format.format(freeMemory / 1024 / 1024) + " MB\n");
sb.append("Allocated Memory: " + format.format(allocatedMemory / 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("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("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"); sb.append("\n");
try { try {
@SuppressWarnings("restriction") @SuppressWarnings("restriction")
com.sun.management.OperatingSystemMXBean operatingSystemMXBean = (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean(); com.sun.management.OperatingSystemMXBean operatingSystemMXBean = (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
@SuppressWarnings("restriction") @SuppressWarnings("restriction")
double processLoad = operatingSystemMXBean.getProcessCpuLoad(); double processLoad = operatingSystemMXBean.getProcessCpuLoad();
@SuppressWarnings("restriction") @SuppressWarnings("restriction")
double systemLoad = operatingSystemMXBean.getSystemCpuLoad(); double systemLoad = operatingSystemMXBean.getSystemCpuLoad();
int processors = runtime.availableProcessors(); int processors = runtime.availableProcessors();
sb.append("Available Processors: " + processors + "\n"); sb.append("Available Processors: " + processors + "\n");
sb.append("Process CPU Load: " + Math.round(processLoad * 100) + "%\n"); sb.append("Process CPU Load: " + Math.round(processLoad * 100) + "%\n");
sb.append("System CPU Load: " + Math.round(systemLoad * 100) + "%\n"); sb.append("System CPU Load: " + Math.round(systemLoad * 100) + "%\n");
GUI.sysText.setText(sb.toString()); GUI.sysText.setText(sb.toString());
} catch (Exception ignore) {} } catch (Exception ignore) {
}
try {TimeUnit.MILLISECONDS.sleep(1000);} catch (InterruptedException e) {} try {
} TimeUnit.MILLISECONDS.sleep(1000);
} } catch (InterruptedException e) {
} }
}
}
}
} }

View File

@ -1,7 +1,5 @@
package com.loohp.limbo.entity; package com.loohp.limbo.entity;
import java.util.UUID;
import com.loohp.limbo.Limbo; import com.loohp.limbo.Limbo;
import com.loohp.limbo.entity.DataWatcher.WatchableField; import com.loohp.limbo.entity.DataWatcher.WatchableField;
import com.loohp.limbo.entity.DataWatcher.WatchableObjectType; 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.utils.Rotation3f;
import com.loohp.limbo.world.World; import com.loohp.limbo.world.World;
import java.util.UUID;
public class ArmorStand extends LivingEntity { public class ArmorStand extends LivingEntity {
@WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x01) @WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x01)
protected boolean small = false; protected boolean small = false;
@WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x04) @WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x04)
protected boolean arms = false; protected boolean arms = false;
@WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x08) @WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x08)
protected boolean noBasePlate = false; protected boolean noBasePlate = false;
@WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x10) @WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x10)
protected boolean marker = false; protected boolean marker = false;
@WatchableField(MetadataIndex = 15, WatchableObjectType = WatchableObjectType.ROTATION) @WatchableField(MetadataIndex = 15, WatchableObjectType = WatchableObjectType.ROTATION)
protected Rotation3f headRotation = new Rotation3f(0.0, 0.0, 0.0); protected Rotation3f headRotation = new Rotation3f(0.0, 0.0, 0.0);
@WatchableField(MetadataIndex = 16, WatchableObjectType = WatchableObjectType.ROTATION) @WatchableField(MetadataIndex = 16, WatchableObjectType = WatchableObjectType.ROTATION)
protected Rotation3f bodyRotation = new Rotation3f(0.0, 0.0, 0.0); protected Rotation3f bodyRotation = new Rotation3f(0.0, 0.0, 0.0);
@WatchableField(MetadataIndex = 17, WatchableObjectType = WatchableObjectType.ROTATION) @WatchableField(MetadataIndex = 17, WatchableObjectType = WatchableObjectType.ROTATION)
protected Rotation3f leftArmRotation = new Rotation3f(-10.0, 0.0, -10.0); protected Rotation3f leftArmRotation = new Rotation3f(-10.0, 0.0, -10.0);
@WatchableField(MetadataIndex = 18, WatchableObjectType = WatchableObjectType.ROTATION) @WatchableField(MetadataIndex = 18, WatchableObjectType = WatchableObjectType.ROTATION)
protected Rotation3f rightArmRotation = new Rotation3f(-15.0, 0.0, 10.0); protected Rotation3f rightArmRotation = new Rotation3f(-15.0, 0.0, 10.0);
@WatchableField(MetadataIndex = 19, WatchableObjectType = WatchableObjectType.ROTATION) @WatchableField(MetadataIndex = 19, WatchableObjectType = WatchableObjectType.ROTATION)
protected Rotation3f leftLegRotation = new Rotation3f(-1.0, 0.0, -1.0); protected Rotation3f leftLegRotation = new Rotation3f(-1.0, 0.0, -1.0);
@WatchableField(MetadataIndex = 20, WatchableObjectType = WatchableObjectType.ROTATION) @WatchableField(MetadataIndex = 20, WatchableObjectType = WatchableObjectType.ROTATION)
protected Rotation3f rightLegRotation = new Rotation3f(1.0, 0.0, 1.0); 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) { 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); 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) { 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); 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) { 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); this(Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), world, x, y, z, yaw, pitch);
} }
public ArmorStand(UUID uuid, Location location) { public ArmorStand(UUID uuid, Location location) {
this(Limbo.getInstance().getNextEntityId(), uuid, location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); this(Limbo.getInstance().getNextEntityId(), uuid, location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
} }
public ArmorStand(Location location) { public ArmorStand(Location location) {
this(Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); this(Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
} }
public boolean isSmall() { public boolean isSmall() {
return small; return small;
} }
public void setSmall(boolean small) { public void setSmall(boolean small) {
this.small = small; this.small = small;
} }
public boolean showArms() { public boolean showArms() {
return arms; return arms;
} }
public void setArms(boolean arms) { public void setArms(boolean arms) {
this.arms = arms; this.arms = arms;
} }
public boolean hasNoBasePlate() { public boolean hasNoBasePlate() {
return noBasePlate; return noBasePlate;
} }
public void setNoBasePlate(boolean noBasePlate) { public void setNoBasePlate(boolean noBasePlate) {
this.noBasePlate = noBasePlate; this.noBasePlate = noBasePlate;
} }
public boolean isMarker() { public boolean isMarker() {
return marker; return marker;
} }
public void setMarker(boolean marker) { public void setMarker(boolean marker) {
this.marker = marker; this.marker = marker;
} }
public Rotation3f getHeadRotation() { public Rotation3f getHeadRotation() {
return headRotation; return headRotation;
} }
public void setHeadRotation(Rotation3f headRotation) { public void setHeadRotation(Rotation3f headRotation) {
this.headRotation = headRotation; this.headRotation = headRotation;
} }
public Rotation3f getBodyRotation() { public Rotation3f getBodyRotation() {
return bodyRotation; return bodyRotation;
} }
public void setBodyRotation(Rotation3f bodyRotation) { public void setBodyRotation(Rotation3f bodyRotation) {
this.bodyRotation = bodyRotation; this.bodyRotation = bodyRotation;
} }
public Rotation3f getLeftArmRotation() { public Rotation3f getLeftArmRotation() {
return leftArmRotation; return leftArmRotation;
} }
public void setLeftArmRotation(Rotation3f leftArmRotation) { public void setLeftArmRotation(Rotation3f leftArmRotation) {
this.leftArmRotation = leftArmRotation; this.leftArmRotation = leftArmRotation;
} }
public Rotation3f getRightArmRotation() { public Rotation3f getRightArmRotation() {
return rightArmRotation; return rightArmRotation;
} }
public void setRightArmRotation(Rotation3f rightArmRotation) { public void setRightArmRotation(Rotation3f rightArmRotation) {
this.rightArmRotation = rightArmRotation; this.rightArmRotation = rightArmRotation;
} }
public Rotation3f getLeftLegRotation() { public Rotation3f getLeftLegRotation() {
return leftLegRotation; return leftLegRotation;
} }
public void setLeftLegRotation(Rotation3f leftLegRotation) { public void setLeftLegRotation(Rotation3f leftLegRotation) {
this.leftLegRotation = leftLegRotation; this.leftLegRotation = leftLegRotation;
} }
public Rotation3f getRightLegRotation() { public Rotation3f getRightLegRotation() {
return rightLegRotation; return rightLegRotation;
} }
public void setRightLegRotation(Rotation3f rightLegRotation) { public void setRightLegRotation(Rotation3f rightLegRotation) {
this.rightLegRotation = rightLegRotation; this.rightLegRotation = rightLegRotation;
} }
} }

View File

@ -12,167 +12,171 @@ import java.util.Map.Entry;
public class DataWatcher { public class DataWatcher {
private Entity entity; private final Entity entity;
private Map<Field, WatchableObject> values; private final Map<Field, WatchableObject> values;
public DataWatcher(Entity entity) { public DataWatcher(Entity entity) {
this.entity = entity; this.entity = entity;
this.values = new HashMap<>(); this.values = new HashMap<>();
Class<?> clazz = entity.getClass(); Class<?> clazz = entity.getClass();
while (clazz != null) { while (clazz != null) {
for (Field field : clazz.getDeclaredFields()) { for (Field field : clazz.getDeclaredFields()) {
WatchableField a = field.getAnnotation(WatchableField.class); WatchableField a = field.getAnnotation(WatchableField.class);
if (a != null) { if (a != null) {
field.setAccessible(true); field.setAccessible(true);
try { try {
values.put(field, new WatchableObject(field.get(entity), a.MetadataIndex(), a.WatchableObjectType(), a.IsOptional(), a.IsBitmask(), a.Bitmask())); values.put(field, new WatchableObject(field.get(entity), a.MetadataIndex(), a.WatchableObjectType(), a.IsOptional(), a.IsBitmask(), a.Bitmask()));
} catch (IllegalArgumentException | IllegalAccessException e) { } catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
clazz = clazz.getSuperclass(); clazz = clazz.getSuperclass();
} }
} }
public Entity getEntity() { public Entity getEntity() {
return entity; return entity;
} }
public boolean isValid() { public boolean isValid() {
return entity.isValid(); return entity.isValid();
} }
public synchronized Map<Field, WatchableObject> update() throws IllegalArgumentException, IllegalAccessException { public synchronized Map<Field, WatchableObject> update() throws IllegalArgumentException, IllegalAccessException {
if (!isValid()) { if (!isValid()) {
return null; return null;
} }
Map<Field, WatchableObject> updated = new HashMap<>(); Map<Field, WatchableObject> updated = new HashMap<>();
for (Entry<Field, WatchableObject> entry : values.entrySet()) { for (Entry<Field, WatchableObject> entry : values.entrySet()) {
Field field = entry.getKey(); Field field = entry.getKey();
WatchableObject watchableObj = entry.getValue(); WatchableObject watchableObj = entry.getValue();
field.setAccessible(true); field.setAccessible(true);
Object newValue = field.get(entity); 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()))) { if ((newValue == null && watchableObj.getValue() != null) || (newValue != null && watchableObj.getValue() == null) || (newValue != null && watchableObj.getValue() != null && !newValue.equals(watchableObj.getValue()))) {
watchableObj.setValue(newValue); watchableObj.setValue(newValue);
updated.put(field, watchableObj); updated.put(field, watchableObj);
} }
} }
return updated; return updated;
} }
public Map<Field, WatchableObject> getWatchableObjects() { public Map<Field, WatchableObject> getWatchableObjects() {
return Collections.unmodifiableMap(values); return Collections.unmodifiableMap(values);
} }
public static class WatchableObject { 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);
private int index; int typeId;
private WatchableObjectType type; int optionalTypeId;
private boolean optional;
private boolean isBitmask;
private int bitmask;
private Object value; WatchableObjectType(int typeId, int optionalTypeId) {
this.typeId = typeId;
this.optionalTypeId = optionalTypeId;
}
public WatchableObject(Object value, int index, WatchableObjectType type, boolean optional, boolean isBitmask, int bitmask) { WatchableObjectType(int typeId) {
this.index = index; this(typeId, -1);
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) { public int getTypeId() {
this(value, index, type, false, isBitmask, bitmask); return typeId;
} }
public WatchableObject(Object value, int index, WatchableObjectType type, boolean optional) { public int getOptionalTypeId() {
this(value, index, type, optional, false, 0x00); return optionalTypeId;
} }
}
public WatchableObject(Object value, int index, WatchableObjectType type) { @Retention(RetentionPolicy.RUNTIME)
this(value, index, type, false, false, 0x00); @Target(ElementType.FIELD)
} public @interface WatchableField {
int MetadataIndex();
public Object getValue() { WatchableObjectType WatchableObjectType();
return value;
}
public void setValue(Object newValue) { boolean IsOptional() default false;
this.value = newValue;
}
public int getIndex() { boolean IsBitmask() default false;
return index;
}
public WatchableObjectType getType() { int Bitmask() default 0x00;
return type; }
}
public boolean isOptional() { public static class WatchableObject {
return optional;
}
public boolean isBitmask() { private final int index;
return isBitmask; private final WatchableObjectType type;
} private final boolean optional;
private final boolean isBitmask;
private final int bitmask;
public int getBitmask() { private Object value;
return bitmask;
}
}
@Retention(RetentionPolicy.RUNTIME) public WatchableObject(Object value, int index, WatchableObjectType type, boolean optional, boolean isBitmask, int bitmask) {
@Target(ElementType.FIELD) this.index = index;
public static @interface WatchableField { this.type = type;
int MetadataIndex(); this.optional = optional;
WatchableObjectType WatchableObjectType(); this.isBitmask = isBitmask;
boolean IsOptional() default false; this.bitmask = bitmask;
boolean IsBitmask() default false; this.value = value;
int Bitmask() default 0x00; }
}
public static enum WatchableObjectType { public WatchableObject(Object value, int index, WatchableObjectType type, boolean isBitmask, int bitmask) {
BYTE(0), this(value, index, type, false, isBitmask, bitmask);
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; public WatchableObject(Object value, int index, WatchableObjectType type, boolean optional) {
int optionalTypeId; this(value, index, type, optional, false, 0x00);
}
WatchableObjectType(int typeId, int optionalTypeId) { public WatchableObject(Object value, int index, WatchableObjectType type) {
this.typeId = typeId; this(value, index, type, false, false, 0x00);
this.optionalTypeId = optionalTypeId; }
}
WatchableObjectType(int typeId) { public Object getValue() {
this(typeId, -1); return value;
} }
public int getTypeId() { public void setValue(Object newValue) {
return typeId; this.value = newValue;
} }
public int getOptionalTypeId() { public int getIndex() {
return optionalTypeId; return index;
} }
}
public WatchableObjectType getType() {
return type;
}
public boolean isOptional() {
return optional;
}
public boolean isBitmask() {
return isBitmask;
}
public int getBitmask() {
return bitmask;
}
}
} }

View File

@ -1,283 +1,280 @@
package com.loohp.limbo.entity; package com.loohp.limbo.entity;
import java.util.UUID;
import com.loohp.limbo.Limbo; import com.loohp.limbo.Limbo;
import com.loohp.limbo.entity.DataWatcher.WatchableField; import com.loohp.limbo.entity.DataWatcher.WatchableField;
import com.loohp.limbo.entity.DataWatcher.WatchableObjectType; import com.loohp.limbo.entity.DataWatcher.WatchableObjectType;
import com.loohp.limbo.location.Location; import com.loohp.limbo.location.Location;
import com.loohp.limbo.world.World; import com.loohp.limbo.world.World;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.chat.TextComponent;
import java.util.UUID;
public abstract class Entity { public abstract class Entity {
@WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x01) protected final EntityType type;
protected boolean onFire = false; @WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x01)
@WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x02) protected boolean onFire = false;
protected boolean crouching = false; @WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x02)
@WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x04) protected boolean crouching = false;
protected boolean unused = false; @WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x04)
@WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x08) protected boolean unused = false;
protected boolean sprinting = false; @WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x08)
@WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x10) protected boolean sprinting = false;
protected boolean swimming = false; @WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x10)
@WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x20) protected boolean swimming = false;
protected boolean invisible = false; @WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x20)
@WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x40) protected boolean invisible = false;
protected boolean glowing = false; @WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x40)
@WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x80) protected boolean glowing = false;
protected boolean elytraFlying = false; @WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x80)
@WatchableField(MetadataIndex = 1, WatchableObjectType = WatchableObjectType.VARINT) protected boolean elytraFlying = false;
protected int air = 300; @WatchableField(MetadataIndex = 1, WatchableObjectType = WatchableObjectType.VARINT)
@WatchableField(MetadataIndex = 2, WatchableObjectType = WatchableObjectType.CHAT, IsOptional = true) protected int air = 300;
protected BaseComponent[] customName = null; @WatchableField(MetadataIndex = 2, WatchableObjectType = WatchableObjectType.CHAT, IsOptional = true)
@WatchableField(MetadataIndex = 3, WatchableObjectType = WatchableObjectType.BOOLEAN) protected BaseComponent[] customName = null;
protected boolean customNameVisible = false; @WatchableField(MetadataIndex = 3, WatchableObjectType = WatchableObjectType.BOOLEAN)
@WatchableField(MetadataIndex = 4, WatchableObjectType = WatchableObjectType.BOOLEAN) protected boolean customNameVisible = false;
protected boolean silent = false; @WatchableField(MetadataIndex = 4, WatchableObjectType = WatchableObjectType.BOOLEAN)
@WatchableField(MetadataIndex = 5, WatchableObjectType = WatchableObjectType.BOOLEAN) protected boolean silent = false;
protected boolean noGravity = false; @WatchableField(MetadataIndex = 5, WatchableObjectType = WatchableObjectType.BOOLEAN)
@WatchableField(MetadataIndex = 6, WatchableObjectType = WatchableObjectType.POSE) protected boolean noGravity = false;
protected Pose pose = Pose.STANDING; @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;
protected final EntityType type; 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;
}
protected int entityId; public Entity(EntityType type, UUID uuid, World world, double x, double y, double z, float yaw, float pitch) {
protected UUID uuid; this(type, Limbo.getInstance().getNextEntityId(), uuid, world, x, y, z, yaw, pitch);
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) { public Entity(EntityType type, World world, double x, double y, double z, float yaw, float pitch) {
this.type = type; this(type, Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), world, x, y, z, yaw, pitch);
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) { public Entity(EntityType type, UUID uuid, Location location) {
this(type, Limbo.getInstance().getNextEntityId(), uuid, world, x, y, z, yaw, pitch); this(type, Limbo.getInstance().getNextEntityId(), uuid, location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
} }
public Entity(EntityType type, World world, double x, double y, double z, float yaw, float pitch) { public Entity(EntityType type, Location location) {
this(type, Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), world, x, y, z, yaw, pitch); this(type, Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
} }
public Entity(EntityType type, UUID uuid, Location location) { public EntityType getType() {
this(type, Limbo.getInstance().getNextEntityId(), uuid, location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); return type;
} }
public Entity(EntityType type, Location location) { public Location getLocation() {
this(type, Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); return new Location(world, x, y, z, yaw, pitch);
} }
public EntityType getType() { public void teleport(Location location) {
return type; 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 Location getLocation() { public BaseComponent[] getCustomName() {
return new Location(world, x, y, z, yaw, pitch); return customName;
} }
public void teleport(Location location) { public void setCustomName(String name) {
this.world = location.getWorld(); this.customName = name == null ? null : new BaseComponent[]{new TextComponent(name)};
this.x = location.getX(); }
this.y = location.getY();
this.z = location.getZ();
this.yaw = location.getYaw();
this.pitch = location.getPitch();
}
public BaseComponent[] getCustomName() { public void setCustomName(BaseComponent component) {
return customName; this.customName = component == null ? null : new BaseComponent[]{component};
} }
public void setCustomName(String name) { public void setCustomName(BaseComponent[] components) {
this.customName = name == null ? null : new BaseComponent[] {new TextComponent(name)}; this.customName = components;
} }
public void setCustomName(BaseComponent component) { public boolean isOnFire() {
this.customName = component == null ? null : new BaseComponent[] {component}; return onFire;
} }
public void setCustomName(BaseComponent[] components) { public void setOnFire(boolean onFire) {
this.customName = components; this.onFire = onFire;
} }
public boolean isOnFire() { public boolean isCrouching() {
return onFire; return crouching;
} }
public void setOnFire(boolean onFire) { public void setCrouching(boolean crouching) {
this.onFire = onFire; this.crouching = crouching;
} }
public boolean isCrouching() { public boolean isSprinting() {
return crouching; return sprinting;
} }
public void setCrouching(boolean crouching) { public void setSprinting(boolean sprinting) {
this.crouching = crouching; this.sprinting = sprinting;
} }
public boolean isSprinting() { public boolean isSwimming() {
return sprinting; return swimming;
} }
public void setSprinting(boolean sprinting) { public void setSwimming(boolean swimming) {
this.sprinting = sprinting; this.swimming = swimming;
} }
public boolean isSwimming() { public boolean isInvisible() {
return swimming; return invisible;
} }
public void setSwimming(boolean swimming) { public void setInvisible(boolean invisible) {
this.swimming = swimming; this.invisible = invisible;
} }
public boolean isInvisible() { public boolean isGlowing() {
return invisible; return glowing;
} }
public void setInvisible(boolean invisible) { public void setGlowing(boolean glowing) {
this.invisible = invisible; this.glowing = glowing;
} }
public boolean isGlowing() { public boolean isElytraFlying() {
return glowing; return elytraFlying;
} }
public void setGlowing(boolean glowing) { public void setElytraFlying(boolean elytraFlying) {
this.glowing = glowing; this.elytraFlying = elytraFlying;
} }
public boolean isElytraFlying() { public int getAir() {
return elytraFlying; return air;
} }
public void setElytraFlying(boolean elytraFlying) { public void setAir(int air) {
this.elytraFlying = elytraFlying; this.air = air;
} }
public int getAir() { public boolean isCustomNameVisible() {
return air; return customNameVisible;
} }
public void setAir(int air) { public void setCustomNameVisible(boolean customNameVisible) {
this.air = air; this.customNameVisible = customNameVisible;
} }
public boolean isCustomNameVisible() { public boolean isSilent() {
return customNameVisible; return silent;
} }
public void setCustomNameVisible(boolean customNameVisible) { public void setSilent(boolean silent) {
this.customNameVisible = customNameVisible; this.silent = silent;
} }
public boolean isSilent() { public boolean hasGravity() {
return silent; return !noGravity;
} }
public void setSilent(boolean silent) { public void setGravity(boolean gravity) {
this.silent = silent; this.noGravity = !gravity;
} }
public boolean hasGravity() { public Pose getPose() {
return !noGravity; return pose;
} }
public void setGravity(boolean gravity) { public void setPose(Pose pose) {
this.noGravity = !gravity; this.pose = pose;
} }
public Pose getPose() { public World getWorld() {
return pose; return world;
} }
public void setPose(Pose pose) { public void setWorld(World world) {
this.pose = pose; this.world = world;
} }
public World getWorld() { public double getX() {
return world; return x;
} }
public void setWorld(World world) { public void setX(double x) {
this.world = world; this.x = x;
} }
public double getX() { public double getY() {
return x; return y;
} }
public void setX(double x) { public void setY(double y) {
this.x = x; this.y = y;
} }
public double getY() { public double getZ() {
return y; return z;
} }
public void setY(double y) { public void setZ(double z) {
this.y = y; this.z = z;
} }
public double getZ() { public float getYaw() {
return z; return yaw;
} }
public void setZ(double z) { public void setYaw(float yaw) {
this.z = z; this.yaw = yaw;
} }
public float getYaw() { public float getPitch() {
return yaw; return pitch;
} }
public void setYaw(float yaw) { public void setPitch(float pitch) {
this.yaw = yaw; this.pitch = pitch;
} }
public float getPitch() { public int getEntityId() {
return pitch; return entityId;
} }
public void setPitch(float pitch) { public UUID getUniqueId() {
this.pitch = pitch; return uuid;
} }
public int getEntityId() { public boolean isValid() {
return entityId; return world.getEntities().contains(this);
} }
public UUID getUniqueId() { @SuppressWarnings("deprecation")
return uuid; public void remove() {
} Limbo.getInstance().getUnsafe().removeEntity(world, this);
}
public boolean isValid() { @SuppressWarnings("deprecation")
return world.getEntities().contains(this); public DataWatcher getDataWatcher() {
} return Limbo.getInstance().getUnsafe().getDataWatcher(world, this);
}
@SuppressWarnings("deprecation")
public void remove() {
Limbo.getInstance().getUnsafe().removeEntity(world, this);
}
@SuppressWarnings("deprecation")
public DataWatcher getDataWatcher() {
return Limbo.getInstance().getUnsafe().getDataWatcher(world, this);
}
} }

View File

@ -1,13 +1,13 @@
package com.loohp.limbo.entity; package com.loohp.limbo.entity;
import java.util.HashMap;
import java.util.Map;
import com.loohp.limbo.location.Location; import com.loohp.limbo.location.Location;
import com.loohp.limbo.player.Player; import com.loohp.limbo.player.Player;
import com.loohp.limbo.utils.NamespacedKey; import com.loohp.limbo.utils.NamespacedKey;
import com.loohp.limbo.world.World; import com.loohp.limbo.world.World;
import java.util.HashMap;
import java.util.Map;
public enum EntityType { public enum EntityType {
// These strings MUST match the strings in nms.EntityTypes and are case sensitive. // 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); UNKNOWN(null, null, -1, false);
private final String name;
private final Class<? extends Entity> clazz;
private final short typeId;
private final boolean independent;
private final boolean living;
private final NamespacedKey key;
private static final Map<String, EntityType> NAME_MAP = new HashMap<>(); private static final Map<String, EntityType> NAME_MAP = new HashMap<>();
private static final Map<Short, EntityType> ID_MAP = new HashMap<>(); private static final Map<Short, EntityType> ID_MAP = new HashMap<>();
@ -308,11 +301,18 @@ public enum EntityType {
*/ */
} }
private EntityType(String name, Class<? extends Entity> clazz, int typeId) { private final String name;
private final Class<? extends Entity> clazz;
private final short typeId;
private final boolean independent;
private final boolean living;
private final NamespacedKey key;
EntityType(String name, Class<? extends Entity> clazz, int typeId) {
this(name, clazz, typeId, true); this(name, clazz, typeId, true);
} }
private EntityType(String name, Class<? extends Entity> clazz, int typeId, boolean independent) { EntityType(String name, Class<? extends Entity> clazz, int typeId, boolean independent) {
this.name = name; this.name = name;
this.clazz = clazz; this.clazz = clazz;
this.typeId = (short) typeId; this.typeId = (short) typeId;
@ -321,34 +321,6 @@ public enum EntityType {
this.key = (name == null) ? null : NamespacedKey.minecraft(name); 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<? extends Entity> 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. * Gets an entity type from its name.
* *
@ -379,6 +351,34 @@ public enum EntityType {
return ID_MAP.get((short) id); 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<? extends Entity> 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 * Some entities cannot be spawned using {@link
* World#spawnEntity(Location, EntityType)} or {@link * World#spawnEntity(Location, EntityType)} or {@link

View File

@ -1,7 +1,5 @@
package com.loohp.limbo.entity; package com.loohp.limbo.entity;
import java.util.UUID;
import com.loohp.limbo.Limbo; import com.loohp.limbo.Limbo;
import com.loohp.limbo.entity.DataWatcher.WatchableField; import com.loohp.limbo.entity.DataWatcher.WatchableField;
import com.loohp.limbo.entity.DataWatcher.WatchableObjectType; 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.BlockPosition;
import com.loohp.limbo.world.World; import com.loohp.limbo.world.World;
import java.util.UUID;
public abstract class LivingEntity extends Entity { public abstract class LivingEntity extends Entity {
@WatchableField(MetadataIndex = 7, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x01) @WatchableField(MetadataIndex = 7, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x01)
protected boolean handActive = false; protected boolean handActive = false;
@WatchableField(MetadataIndex = 7, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x02) @WatchableField(MetadataIndex = 7, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x02)
protected boolean activeHand = false; //false = main hand, true = off hand protected boolean activeHand = false; //false = main hand, true = off hand
@WatchableField(MetadataIndex = 7, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x04) @WatchableField(MetadataIndex = 7, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x04)
protected boolean inRiptideSpinAttack = false; protected boolean inRiptideSpinAttack = false;
@WatchableField(MetadataIndex = 8, WatchableObjectType = WatchableObjectType.FLOAT) @WatchableField(MetadataIndex = 8, WatchableObjectType = WatchableObjectType.FLOAT)
protected float health = 1.0F; protected float health = 1.0F;
@WatchableField(MetadataIndex = 9, WatchableObjectType = WatchableObjectType.VARINT) @WatchableField(MetadataIndex = 9, WatchableObjectType = WatchableObjectType.VARINT)
protected int potionEffectColor = 0; protected int potionEffectColor = 0;
@WatchableField(MetadataIndex = 10, WatchableObjectType = WatchableObjectType.BOOLEAN) @WatchableField(MetadataIndex = 10, WatchableObjectType = WatchableObjectType.BOOLEAN)
protected boolean potionEffectAmbient = false; protected boolean potionEffectAmbient = false;
@WatchableField(MetadataIndex = 11, WatchableObjectType = WatchableObjectType.VARINT) @WatchableField(MetadataIndex = 11, WatchableObjectType = WatchableObjectType.VARINT)
protected int arrowsInEntity = 0; protected int arrowsInEntity = 0;
@WatchableField(MetadataIndex = 12, WatchableObjectType = WatchableObjectType.VARINT) @WatchableField(MetadataIndex = 12, WatchableObjectType = WatchableObjectType.VARINT)
protected int absorption = 0; protected int absorption = 0;
@WatchableField(MetadataIndex = 13, WatchableObjectType = WatchableObjectType.POSITION, IsOptional = true) @WatchableField(MetadataIndex = 13, WatchableObjectType = WatchableObjectType.POSITION, IsOptional = true)
protected BlockPosition sleepingLocation = null; protected BlockPosition sleepingLocation = null;
public LivingEntity(EntityType type, int entityId, UUID uuid, World world, double x, double y, double z, float yaw, float pitch) { 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); 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) { 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); 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) { 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); this(type, Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), world, x, y, z, yaw, pitch);
} }
public LivingEntity(EntityType type, UUID uuid, Location location) { 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()); this(type, Limbo.getInstance().getNextEntityId(), uuid, location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
} }
public LivingEntity(EntityType type, Location location) { 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()); this(type, Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
} }
public boolean isHandActive() { public boolean isHandActive() {
return handActive; return handActive;
} }
public void setHandActive(boolean handActive) { public void setHandActive(boolean handActive) {
this.handActive = handActive; this.handActive = handActive;
} }
public EquipmentSlot getActiveHand() { public EquipmentSlot getActiveHand() {
return activeHand ? EquipmentSlot.OFFHAND : EquipmentSlot.MAINHAND; return activeHand ? EquipmentSlot.OFFHAND : EquipmentSlot.MAINHAND;
} }
public void setActiveHand(EquipmentSlot activeHand) { public void setActiveHand(EquipmentSlot activeHand) {
if (activeHand.equals(EquipmentSlot.MAINHAND)) { if (activeHand.equals(EquipmentSlot.MAINHAND)) {
this.activeHand = false; this.activeHand = false;
} else if (activeHand.equals(EquipmentSlot.OFFHAND)) { } else if (activeHand.equals(EquipmentSlot.OFFHAND)) {
this.activeHand = true; this.activeHand = true;
} else { } else {
throw new IllegalArgumentException("Invalid EquipmentSlot " + activeHand.toString()); throw new IllegalArgumentException("Invalid EquipmentSlot " + activeHand);
} }
} }
public boolean isInRiptideSpinAttack() { public boolean isInRiptideSpinAttack() {
return inRiptideSpinAttack; return inRiptideSpinAttack;
} }
public void setInRiptideSpinAttack(boolean inRiptideSpinAttack) { public void setInRiptideSpinAttack(boolean inRiptideSpinAttack) {
this.inRiptideSpinAttack = inRiptideSpinAttack; this.inRiptideSpinAttack = inRiptideSpinAttack;
} }
public float getHealth() { public float getHealth() {
return health; return health;
} }
public void setHealth(float health) { public void setHealth(float health) {
this.health = health; this.health = health;
} }
public int getPotionEffectColor() { public int getPotionEffectColor() {
return potionEffectColor; return potionEffectColor;
} }
public void setPotionEffectColor(int potionEffectColor) { public void setPotionEffectColor(int potionEffectColor) {
this.potionEffectColor = potionEffectColor; this.potionEffectColor = potionEffectColor;
} }
public boolean isPotionEffectAmbient() { public boolean isPotionEffectAmbient() {
return potionEffectAmbient; return potionEffectAmbient;
} }
public void setPotionEffectAmbient(boolean potionEffectAmbient) { public void setPotionEffectAmbient(boolean potionEffectAmbient) {
this.potionEffectAmbient = potionEffectAmbient; this.potionEffectAmbient = potionEffectAmbient;
} }
public int getArrowsInEntity() { public int getArrowsInEntity() {
return arrowsInEntity; return arrowsInEntity;
} }
public void setArrowsInEntity(int arrowsInEntity) { public void setArrowsInEntity(int arrowsInEntity) {
this.arrowsInEntity = arrowsInEntity; this.arrowsInEntity = arrowsInEntity;
} }
public int getAbsorption() { public int getAbsorption() {
return absorption; return absorption;
} }
public void setAbsorption(int absorption) { public void setAbsorption(int absorption) {
this.absorption = absorption; this.absorption = absorption;
} }
public BlockPosition getSleepingLocation() { public BlockPosition getSleepingLocation() {
return sleepingLocation; return sleepingLocation;
} }
public void setSleepingLocation(BlockPosition sleepingLocation) { public void setSleepingLocation(BlockPosition sleepingLocation) {
this.sleepingLocation = sleepingLocation; this.sleepingLocation = sleepingLocation;
} }
} }

View File

@ -2,33 +2,33 @@ package com.loohp.limbo.entity;
public enum Pose { public enum Pose {
STANDING(0), STANDING(0),
FALL_FLYING(1), FALL_FLYING(1),
SLEEPING(2), SLEEPING(2),
SWIMMING(3), SWIMMING(3),
SPIN_ATTACK(4), SPIN_ATTACK(4),
SNEAKING(5), SNEAKING(5),
DYING(6); DYING(6);
private static final Pose[] VALUES = values(); private static final Pose[] VALUES = values();
private int id; private final int id;
Pose(int id) { Pose(int id) {
this.id = id; this.id = id;
} }
public int getId() { public static Pose fromId(int id) {
return id; for (Pose pose : VALUES) {
} if (id == pose.id) {
return pose;
}
}
return null;
}
public static Pose fromId(int id) { public int getId() {
for (Pose pose : VALUES) { return id;
if (id == pose.id) { }
return pose;
}
}
return null;
}
} }

View File

@ -2,8 +2,8 @@ package com.loohp.limbo.events;
public interface Cancellable { public interface Cancellable {
public void setCancelled(boolean cancelled); boolean isCancelled();
public boolean isCancelled(); void setCancelled(boolean cancelled);
} }

View File

@ -1,14 +1,10 @@
package com.loohp.limbo.events; package com.loohp.limbo.events;
import java.lang.annotation.Documented; import java.lang.annotation.*;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented @Documented
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface EventHandler { public @interface EventHandler {
EventPriority priority() default EventPriority.NORMAL; EventPriority priority() default EventPriority.NORMAL;
} }

View File

@ -1,37 +1,37 @@
package com.loohp.limbo.events; package com.loohp.limbo.events;
public enum EventPriority { public enum EventPriority {
LOWEST(0), LOWEST(0),
LOW(1), LOW(1),
NORMAL(2), NORMAL(2),
HIGH(3), HIGH(3),
HIGHEST(4), HIGHEST(4),
MONITOR(5); MONITOR(5);
int order; int order;
EventPriority(int order) { EventPriority(int order) {
this.order = order; this.order = order;
} }
public int getOrder() { public static EventPriority getByOrder(int order) {
return order; for (EventPriority each : EventPriority.values()) {
} if (each.getOrder() == order) {
return each;
}
}
return null;
}
public static EventPriority getByOrder(int order) { public static EventPriority[] getPrioritiesInOrder() {
for (EventPriority each : EventPriority.values()) { EventPriority[] array = new EventPriority[EventPriority.values().length];
if (each.getOrder() == order) { for (int i = 0; i < array.length; i++) {
return each; array[i] = EventPriority.getByOrder(i);
} }
} return array;
return null; }
}
public static EventPriority[] getPrioritiesInOrder() { public int getOrder() {
EventPriority[] array = new EventPriority[EventPriority.values().length]; return order;
for (int i = 0; i < array.length; i++) { }
array[i] = EventPriority.getByOrder(i);
}
return array;
}
} }

View File

@ -1,58 +1,58 @@
package com.loohp.limbo.events; package com.loohp.limbo.events;
import com.loohp.limbo.plugins.LimboPlugin;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.loohp.limbo.plugins.LimboPlugin;
public class EventsManager { public class EventsManager {
private List<ListenerPair> listeners; private final List<ListenerPair> listeners;
public EventsManager() { public EventsManager() {
listeners = new ArrayList<>(); listeners = new ArrayList<>();
} }
public <T extends Event> T callEvent(T event) { public <T extends Event> T callEvent(T event) {
for (EventPriority priority : EventPriority.getPrioritiesInOrder()) { for (EventPriority priority : EventPriority.getPrioritiesInOrder()) {
for (ListenerPair entry : listeners) { for (ListenerPair entry : listeners) {
Listener listener = entry.listener; Listener listener = entry.listener;
for (Method method : listener.getClass().getMethods()) { for (Method method : listener.getClass().getMethods()) {
if (method.isAnnotationPresent(EventHandler.class)) { if (method.isAnnotationPresent(EventHandler.class)) {
if (method.getAnnotation(EventHandler.class).priority().equals(priority)) { if (method.getAnnotation(EventHandler.class).priority().equals(priority)) {
if (method.getParameterCount() == 1 && method.getParameterTypes()[0].equals(event.getClass())) { if (method.getParameterCount() == 1 && method.getParameterTypes()[0].equals(event.getClass())) {
try { try {
method.invoke(listener, event); method.invoke(listener, event);
} catch (Exception e) { } catch (Exception e) {
System.err.println("Error while passing " + event.getClass().getCanonicalName() + " to the plugin \"" + entry.plugin.getName() + "\""); System.err.println("Error while passing " + event.getClass().getCanonicalName() + " to the plugin \"" + entry.plugin.getName() + "\"");
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
} }
} }
} }
} }
return event; return event;
} }
public void registerEvents(LimboPlugin plugin, Listener listener) { public void registerEvents(LimboPlugin plugin, Listener listener) {
listeners.add(new ListenerPair(plugin, listener)); listeners.add(new ListenerPair(plugin, listener));
} }
public void unregisterAllListeners(LimboPlugin plugin) { public void unregisterAllListeners(LimboPlugin plugin) {
listeners.removeIf(each -> each.plugin.equals(plugin)); listeners.removeIf(each -> each.plugin.equals(plugin));
} }
protected static class ListenerPair { protected static class ListenerPair {
public LimboPlugin plugin; public LimboPlugin plugin;
public Listener listener; public Listener listener;
public ListenerPair(LimboPlugin plugin, Listener listener) { public ListenerPair(LimboPlugin plugin, Listener listener) {
this.plugin = plugin; this.plugin = plugin;
this.listener = listener; this.listener = listener;
} }
} }
} }

View File

@ -5,41 +5,41 @@ import com.loohp.limbo.player.Player;
public class PlayerChatEvent extends PlayerEvent implements Cancellable { public class PlayerChatEvent extends PlayerEvent implements Cancellable {
private String prefix; private String prefix;
private String message; private String message;
private boolean cancelled; private boolean cancelled;
public PlayerChatEvent(Player player, String prefix, String message, boolean cancelled) { public PlayerChatEvent(Player player, String prefix, String message, boolean cancelled) {
super(player); super(player);
this.prefix = prefix; this.prefix = prefix;
this.message = message; this.message = message;
this.cancelled = cancelled; this.cancelled = cancelled;
} }
public String getPrefix() { public String getPrefix() {
return prefix; return prefix;
} }
public void setPrefix(String prefix) { public void setPrefix(String prefix) {
this.prefix = prefix; this.prefix = prefix;
} }
public String getMessage() { public String getMessage() {
return message; return message;
} }
public void setMessage(String message) { public void setMessage(String message) {
this.message = message; this.message = message;
} }
@Override @Override
public void setCancelled(boolean cancelled) { public boolean isCancelled() {
this.cancelled = cancelled; return cancelled;
} }
@Override @Override
public boolean isCancelled() { public void setCancelled(boolean cancelled) {
return cancelled; this.cancelled = cancelled;
} }
} }

View File

@ -5,14 +5,14 @@ import com.loohp.limbo.player.Player;
public class PlayerEvent extends Event { public class PlayerEvent extends Event {
private Player player; private final Player player;
public PlayerEvent(Player player) { public PlayerEvent(Player player) {
this.player = player; this.player = player;
} }
public Player getPlayer() { public Player getPlayer() {
return player; return player;
} }
} }

View File

@ -5,18 +5,18 @@ import com.loohp.limbo.player.Player;
public class PlayerJoinEvent extends PlayerEvent { public class PlayerJoinEvent extends PlayerEvent {
private Location spawnLocation; private Location spawnLocation;
public PlayerJoinEvent(Player player, Location spawnLoc) { public PlayerJoinEvent(Player player, Location spawnLoc) {
super(player); super(player);
spawnLocation = spawnLoc; spawnLocation = spawnLoc;
} }
public Location getSpawnLocation() { public Location getSpawnLocation() {
return spawnLocation; return spawnLocation;
} }
public void setSpawnLocation(Location spawnLocation) { public void setSpawnLocation(Location spawnLocation) {
this.spawnLocation = spawnLocation; this.spawnLocation = spawnLocation;
} }
} }

View File

@ -3,41 +3,40 @@ package com.loohp.limbo.events.player;
import com.loohp.limbo.events.Cancellable; import com.loohp.limbo.events.Cancellable;
import com.loohp.limbo.events.Event; import com.loohp.limbo.events.Event;
import com.loohp.limbo.server.ClientConnection; import com.loohp.limbo.server.ClientConnection;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
public class PlayerLoginEvent extends Event implements Cancellable { public class PlayerLoginEvent extends Event implements Cancellable {
private ClientConnection connection; private final ClientConnection connection;
private boolean cancelled; private boolean cancelled;
private BaseComponent[] cancelReason; private BaseComponent[] cancelReason;
public PlayerLoginEvent(ClientConnection connection, boolean cancelled, BaseComponent... cancelReason) { public PlayerLoginEvent(ClientConnection connection, boolean cancelled, BaseComponent... cancelReason) {
this.connection = connection; this.connection = connection;
this.cancelled = cancelled; this.cancelled = cancelled;
this.cancelReason = cancelReason; this.cancelReason = cancelReason;
} }
public ClientConnection getConnection() { public ClientConnection getConnection() {
return connection; return connection;
} }
public BaseComponent[] getCancelReason() { public BaseComponent[] getCancelReason() {
return cancelReason; return cancelReason;
} }
public void setCancelReason(BaseComponent... cancelReason) { public void setCancelReason(BaseComponent... cancelReason) {
this.cancelReason = cancelReason; this.cancelReason = cancelReason;
} }
@Override @Override
public void setCancelled(boolean cancelled) { public boolean isCancelled() {
this.cancelled = cancelled; return cancelled;
} }
@Override @Override
public boolean isCancelled() { public void setCancelled(boolean cancelled) {
return cancelled; this.cancelled = cancelled;
} }
} }

View File

@ -4,8 +4,8 @@ import com.loohp.limbo.player.Player;
public class PlayerQuitEvent extends PlayerEvent { public class PlayerQuitEvent extends PlayerEvent {
public PlayerQuitEvent(Player player) { public PlayerQuitEvent(Player player) {
super(player); super(player);
} }
} }

View File

@ -14,13 +14,13 @@ public class PlayerSelectedSlotChangeEvent extends PlayerEvent implements Cancel
} }
@Override @Override
public void setCancelled(boolean cancelled) { public boolean isCancelled() {
this.cancel = cancelled; return cancel;
} }
@Override @Override
public boolean isCancelled() { public void setCancelled(boolean cancelled) {
return cancel; this.cancel = cancelled;
} }
public byte getSlot() { public byte getSlot() {

View File

@ -5,8 +5,8 @@ import com.loohp.limbo.player.Player;
public class PlayerTeleportEvent extends PlayerMoveEvent { public class PlayerTeleportEvent extends PlayerMoveEvent {
public PlayerTeleportEvent(Player player, Location from, Location to) { public PlayerTeleportEvent(Player player, Location from, Location to) {
super(player, from, to); super(player, from, to);
} }
} }

View File

@ -1,82 +1,81 @@
package com.loohp.limbo.events.status; package com.loohp.limbo.events.status;
import java.awt.image.BufferedImage;
import com.loohp.limbo.events.Event; import com.loohp.limbo.events.Event;
import com.loohp.limbo.server.ClientConnection; import com.loohp.limbo.server.ClientConnection;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
import java.awt.image.BufferedImage;
public class StatusPingEvent extends Event { public class StatusPingEvent extends Event {
private ClientConnection connection; private final ClientConnection connection;
private String version; private String version;
private int protocol; private int protocol;
private BaseComponent[] motd; private BaseComponent[] motd;
private int maxPlayers; private int maxPlayers;
private int playersOnline; private int playersOnline;
private BufferedImage favicon; private BufferedImage favicon;
public StatusPingEvent(ClientConnection connection, String version, int protocol, BaseComponent[] motd, int maxPlayers, int playersOnline, BufferedImage favicon) { public StatusPingEvent(ClientConnection connection, String version, int protocol, BaseComponent[] motd, int maxPlayers, int playersOnline, BufferedImage favicon) {
this.connection = connection; this.connection = connection;
this.version = version; this.version = version;
this.protocol = protocol; this.protocol = protocol;
this.motd = motd; this.motd = motd;
this.maxPlayers = maxPlayers; this.maxPlayers = maxPlayers;
this.playersOnline = playersOnline; this.playersOnline = playersOnline;
this.favicon = favicon; this.favicon = favicon;
} }
public ClientConnection getConnection() { public ClientConnection getConnection() {
return connection; return connection;
} }
public String getVersion() { public String getVersion() {
return version; return version;
} }
public void setVersion(String version) { public void setVersion(String version) {
this.version = version; this.version = version;
} }
public int getProtocol() { public int getProtocol() {
return protocol; return protocol;
} }
public void setProtocol(int protocol) { public void setProtocol(int protocol) {
this.protocol = protocol; this.protocol = protocol;
} }
public BaseComponent[] getMotd() { public BaseComponent[] getMotd() {
return motd; return motd;
} }
public void setMotd(BaseComponent[] motd) { public void setMotd(BaseComponent[] motd) {
this.motd = motd; this.motd = motd;
} }
public int getMaxPlayers() { public int getMaxPlayers() {
return maxPlayers; return maxPlayers;
} }
public void setMaxPlayers(int maxPlayers) { public void setMaxPlayers(int maxPlayers) {
this.maxPlayers = maxPlayers; this.maxPlayers = maxPlayers;
} }
public int getPlayersOnline() { public int getPlayersOnline() {
return playersOnline; return playersOnline;
} }
public void setPlayersOnline(int playersOnline) { public void setPlayersOnline(int playersOnline) {
this.playersOnline = playersOnline; this.playersOnline = playersOnline;
} }
public BufferedImage getFavicon() { public BufferedImage getFavicon() {
return favicon; return favicon;
} }
public void setFavicon(BufferedImage favicon) { public void setFavicon(BufferedImage favicon) {
this.favicon = favicon; this.favicon = favicon;
} }
} }

View File

@ -1,148 +1,137 @@
package com.loohp.limbo.file; package com.loohp.limbo.file;
import java.io.ByteArrayOutputStream; import com.loohp.limbo.utils.YamlOrder;
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 org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.representer.Representer; 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 { public class FileConfiguration {
private Map<String, Object> mapping; private Map<String, Object> mapping;
private String header; private String header;
public FileConfiguration(File file) throws IOException { public FileConfiguration(File file) throws IOException {
if (file.exists()) { if (file.exists()) {
InputStreamReader reader = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8); InputStreamReader reader = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8);
reloadConfig(reader); reloadConfig(reader);
reader.close(); reader.close();
} else { } else {
mapping = new LinkedHashMap<>(); mapping = new LinkedHashMap<>();
} }
} }
public FileConfiguration(InputStream input){ public FileConfiguration(InputStream input) {
reloadConfig(new InputStreamReader(input, StandardCharsets.UTF_8)); reloadConfig(new InputStreamReader(input, StandardCharsets.UTF_8));
} }
public FileConfiguration(Reader reader){ public FileConfiguration(Reader reader) {
reloadConfig(reader); reloadConfig(reader);
} }
public FileConfiguration reloadConfig(File file) throws FileNotFoundException { public FileConfiguration reloadConfig(File file) throws FileNotFoundException {
return reloadConfig(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)); return reloadConfig(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8));
} }
public FileConfiguration reloadConfig(InputStream input) { public FileConfiguration reloadConfig(InputStream input) {
return reloadConfig(new InputStreamReader(input, StandardCharsets.UTF_8)); return reloadConfig(new InputStreamReader(input, StandardCharsets.UTF_8));
} }
public FileConfiguration reloadConfig(Reader reader) { public FileConfiguration reloadConfig(Reader reader) {
Yaml yml = new Yaml(); Yaml yml = new Yaml();
mapping = yml.load(reader); mapping = yml.load(reader);
return this; return this;
} }
public void setHeader(String header) { public void setHeader(String header) {
this.header = header; this.header = header;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> T get(String key, Class<T> returnType) { public <T> T get(String key, Class<T> returnType) {
try { try {
String[] tree = key.split("\\."); String[] tree = key.split("\\.");
Map<String, Object> map = mapping; Map<String, Object> map = mapping;
for (int i = 0; i < tree.length - 1; i++) { for (int i = 0; i < tree.length - 1; i++) {
map = (Map<String, Object>) map.get(tree[i]); map = (Map<String, Object>) map.get(tree[i]);
} }
if (returnType.equals(String.class)) { if (returnType.equals(String.class)) {
return (T) map.get(tree[tree.length - 1]).toString(); return (T) map.get(tree[tree.length - 1]).toString();
} }
return returnType.cast(map.get(tree[tree.length - 1])); return returnType.cast(map.get(tree[tree.length - 1]));
} catch (Exception e) { } catch (Exception e) {
return null; return null;
} }
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> void set(String key, T value) { public <T> void set(String key, T value) {
String[] tree = key.split("\\."); String[] tree = key.split("\\.");
Map<String, Object> map = mapping; Map<String, Object> map = mapping;
for (int i = 0; i < tree.length - 1; i++) { for (int i = 0; i < tree.length - 1; i++) {
Map<String, Object> map1 = (Map<String, Object>) map.get(tree[i]); Map<String, Object> map1 = (Map<String, Object>) map.get(tree[i]);
if (map1 == null) { if (map1 == null) {
map1 = new LinkedHashMap<>(); map1 = new LinkedHashMap<>();
map.put(tree[i], map1); map.put(tree[i], map1);
} }
map = map1; map = map1;
} }
if (value != null) { if (value != null) {
map.put(tree[tree.length - 1], (T) value); map.put(tree[tree.length - 1], value);
} else { } else {
map.remove(tree[tree.length - 1]); map.remove(tree[tree.length - 1]);
} }
} }
public String saveToString() throws IOException { public String saveToString() throws IOException {
DumperOptions options = new DumperOptions(); DumperOptions options = new DumperOptions();
options.setIndent(2); options.setIndent(2);
options.setPrettyFlow(true); options.setPrettyFlow(true);
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
Representer customRepresenter = new Representer(); Representer customRepresenter = new Representer();
YamlOrder customProperty = new YamlOrder(); YamlOrder customProperty = new YamlOrder();
customRepresenter.setPropertyUtils(customProperty); customRepresenter.setPropertyUtils(customProperty);
Yaml yaml = new Yaml(customRepresenter, options); Yaml yaml = new Yaml(customRepresenter, options);
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
PrintWriter pw = new PrintWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8)); PrintWriter pw = new PrintWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));
if (header != null) { if (header != null) {
pw.println("#" + header.replace("\n", "\n#")); pw.println("#" + header.replace("\n", "\n#"));
} }
yaml.dump(mapping, pw); yaml.dump(mapping, pw);
pw.flush(); pw.flush();
pw.close(); pw.close();
String str = new String(out.toByteArray(), StandardCharsets.UTF_8); String str = new String(out.toByteArray(), StandardCharsets.UTF_8);
return str; return str;
} }
public void saveConfig(File file) throws IOException { public void saveConfig(File file) throws IOException {
DumperOptions options = new DumperOptions(); DumperOptions options = new DumperOptions();
options.setIndent(2); options.setIndent(2);
options.setPrettyFlow(true); options.setPrettyFlow(true);
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
Representer customRepresenter = new Representer(); Representer customRepresenter = new Representer();
YamlOrder customProperty = new YamlOrder(); YamlOrder customProperty = new YamlOrder();
customRepresenter.setPropertyUtils(customProperty); customRepresenter.setPropertyUtils(customProperty);
Yaml yaml = new Yaml(customRepresenter, options); Yaml yaml = new Yaml(customRepresenter, options);
if (file.getParentFile() != null) { if (file.getParentFile() != null) {
file.getParentFile().mkdirs(); file.getParentFile().mkdirs();
} }
PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)); PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8));
if (header != null) { if (header != null) {
pw.println("#" + header.replace("\n", "\n#")); pw.println("#" + header.replace("\n", "\n#"));
} }
yaml.dump(mapping, pw); yaml.dump(mapping, pw);
pw.flush(); pw.flush();
pw.close(); pw.close();
} }
} }

View File

@ -1,202 +1,193 @@
package com.loohp.limbo.file; 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.Limbo;
import com.loohp.limbo.location.Location; import com.loohp.limbo.location.Location;
import com.loohp.limbo.utils.GameMode; import com.loohp.limbo.utils.GameMode;
import com.loohp.limbo.utils.NamespacedKey; import com.loohp.limbo.utils.NamespacedKey;
import com.loohp.limbo.world.World; 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 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"; 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<BufferedImage> 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;
private File file; public ServerProperties(File file) throws IOException {
private int maxPlayers; this.file = file;
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<BufferedImage> favicon; Properties def = new Properties();
InputStreamReader defStream = new InputStreamReader(getClass().getClassLoader().getResourceAsStream("server.properties"), StandardCharsets.UTF_8);
def.load(defStream);
defStream.close();
public ServerProperties(File file) throws IOException { Properties prop = new Properties();
this.file = file; InputStreamReader stream = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8);
prop.load(stream);
stream.close();
Properties def = new Properties(); for (Entry<Object, Object> entry : def.entrySet()) {
InputStreamReader defStream = new InputStreamReader(getClass().getClassLoader().getResourceAsStream("server.properties"), StandardCharsets.UTF_8); String key = entry.getKey().toString();
def.load(defStream); String value = entry.getValue().toString();
defStream.close(); prop.putIfAbsent(key, value);
}
PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8));
prop.store(pw, COMMENT);
pw.close();
Properties prop = new Properties(); protocol = Limbo.getInstance().serverImplmentationProtocol;
InputStreamReader stream = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8);
prop.load(stream);
stream.close();
for (Entry<Object, Object> entry : def.entrySet()) { maxPlayers = Integer.parseInt(prop.getProperty("max-players"));
String key = entry.getKey().toString(); serverPort = Integer.parseInt(prop.getProperty("server-port"));
String value = entry.getValue().toString(); serverIp = prop.getProperty("server-ip");
prop.putIfAbsent(key, value); String[] level = prop.getProperty("level-name").split(";");
} levelName = new NamespacedKey(level[0]);
PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)); schemFileName = level[1];
prop.store(pw, COMMENT); levelDimension = new NamespacedKey(prop.getProperty("level-dimension"));
pw.close(); 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"));
protocol = Limbo.getInstance().serverImplmentationProtocol; 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();
}
maxPlayers = Integer.parseInt(prop.getProperty("max-players")); Limbo.getInstance().getConsole().sendMessage("Loaded server.properties");
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"); public String getServerImplementationVersion() {
if (png.exists()) { return Limbo.getInstance().serverImplementationVersion;
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();
}
Limbo.getInstance().getConsole().sendMessage("Loaded server.properties"); public boolean isBungeecord() {
} return bungeecord;
}
public String getServerImplementationVersion() { public Optional<BufferedImage> getFavicon() {
return Limbo.getInstance().serverImplementationVersion; return favicon;
} }
public boolean isBungeecord() { public File getFile() {
return bungeecord; return file;
} }
public Optional<BufferedImage> getFavicon() { public int getMaxPlayers() {
return favicon; return maxPlayers;
} }
public File getFile() { public int getServerPort() {
return file; return serverPort;
} }
public int getMaxPlayers() { public String getServerIp() {
return maxPlayers; return serverIp;
} }
public int getServerPort() { public NamespacedKey getLevelName() {
return serverPort; return levelName;
} }
public String getServerIp() { public String getSchemFileName() {
return serverIp; return schemFileName;
} }
public NamespacedKey getLevelName() { public NamespacedKey getLevelDimension() {
return levelName; return levelDimension;
} }
public String getSchemFileName() { public GameMode getDefaultGamemode() {
return schemFileName; return defaultGamemode;
} }
public NamespacedKey getLevelDimension() { public Location getWorldSpawn() {
return levelDimension; return worldSpawn;
} }
public GameMode getDefaultGamemode() { public void setWorldSpawn(Location location) {
return defaultGamemode; this.worldSpawn = location;
} }
public Location getWorldSpawn() { public boolean isReducedDebugInfo() {
return worldSpawn; return reducedDebugInfo;
} }
public void setWorldSpawn(Location location) { public boolean isAllowFlight() {
this.worldSpawn = location; return allowFlight;
} }
public boolean isReducedDebugInfo() { public String getMotdJson() {
return reducedDebugInfo; return motdJson;
} }
public boolean isAllowFlight() { public String getVersionString() {
return allowFlight; return versionString;
} }
public String getMotdJson() { public int getProtocol() {
return motdJson; return protocol;
} }
public String getVersionString() { public int getViewDistance() {
return versionString; return viewDistance;
} }
public int getProtocol() { public double getDefinedTicksPerSecond() {
return protocol; return ticksPerSecond;
} }
public int getViewDistance() { public boolean handshakeVerboseEnabled() {
return viewDistance; return handshakeVerbose;
} }
public double getDefinedTicksPerSecond() {
return ticksPerSecond;
}
public boolean handshakeVerboseEnabled() {
return handshakeVerbose;
}
} }

View File

@ -2,11 +2,11 @@ package com.loohp.limbo.inventory;
public enum EquipmentSlot { public enum EquipmentSlot {
MAINHAND, MAINHAND,
OFFHAND, OFFHAND,
HELMENT, HELMENT,
CHESTPLATE, CHESTPLATE,
LEGGINGS, LEGGINGS,
BOOTS; BOOTS
} }

View File

@ -7,101 +7,147 @@ import com.loohp.limbo.world.World;
public class Location implements Cloneable { public class Location implements Cloneable {
private World world; private World world;
private double x; private double x;
private double y; private double y;
private double z; private double z;
private float yaw; private float yaw;
private float pitch; private float pitch;
public Location(World world, double x, double y, double z, float yaw, float pitch) { public Location(World world, double x, double y, double z, float yaw, float pitch) {
this.world = world; this.world = world;
this.x = x; this.x = x;
this.y = y; this.y = y;
this.z = z; this.z = z;
this.yaw = yaw; this.yaw = yaw;
this.pitch = pitch; this.pitch = pitch;
} }
public Location(World world, double x, double y, double z) { public Location(World world, double x, double y, double z) {
this(world, x, y, z, 0, 0); this(world, x, y, z, 0, 0);
} }
@Override /**
public Location clone() { * Safely converts a double (location coordinate) to an int (block
try { * 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 <code>+/-180</code>
* 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 <code>+/-90</code>
* 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(); return (Location) super.clone();
} catch (CloneNotSupportedException e) { } catch (CloneNotSupportedException e) {
throw new Error(e); throw new Error(e);
} }
} }
public BlockState getBlockState() { public BlockState getBlockState() {
return world.getBlock((int) x,(int) y,(int) z); return world.getBlock((int) x, (int) y, (int) z);
} }
public void setBlockState(BlockState state) { public void setBlockState(BlockState state) {
world.setBlock((int) x, (int) y, (int) z, state); world.setBlock((int) x, (int) y, (int) z, state);
} }
public boolean isWorldLoaded() { public boolean isWorldLoaded() {
return Limbo.getInstance().getWorld(world.getName()) != null; return Limbo.getInstance().getWorld(world.getName()) != null;
} }
public World getWorld() { public World getWorld() {
return world; return world;
} }
public void setWorld(World world) { public void setWorld(World world) {
this.world = world; this.world = world;
} }
public double getX() { public double getX() {
return x; return x;
} }
public void setX(double x) { public void setX(double x) {
this.x = x; this.x = x;
} }
public double getY() { public double getY() {
return y; return y;
} }
public void setY(double y) { public void setY(double y) {
this.y = y; this.y = y;
} }
public double getZ() { public double getZ() {
return z; return z;
} }
public void setZ(double z) { public void setZ(double z) {
this.z = z; this.z = z;
} }
public float getYaw() { public float getYaw() {
return yaw; return yaw;
} }
public void setYaw(float yaw) { public void setYaw(float yaw) {
this.yaw = yaw; this.yaw = yaw;
} }
public float getPitch() { public float getPitch() {
return pitch; return pitch;
} }
public void setPitch(float pitch) { public void setPitch(float pitch) {
this.pitch = pitch; this.pitch = pitch;
} }
/** /**
* Gets a unit-vector pointing in the direction that this Location is * Gets a unit-vector pointing in the direction that this Location is
* facing. * facing.
* *
* @return a vector pointing the direction of this location's {@link * @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() { public Vector getDirection() {
Vector vector = new Vector(); Vector vector = new Vector();
@ -158,10 +204,10 @@ public class Location implements Cloneable {
/** /**
* Adds the location by another. * Adds the location by another.
* *
* @see Vector
* @param vec The other location * @param vec The other location
* @return the same location * @return the same location
* @throws IllegalArgumentException for differing worlds * @throws IllegalArgumentException for differing worlds
* @see Vector
*/ */
public Location add(Location vec) { public Location add(Location vec) {
if (vec == null || vec.getWorld() != getWorld()) { if (vec == null || vec.getWorld() != getWorld()) {
@ -177,9 +223,9 @@ public class Location implements Cloneable {
/** /**
* Adds the location by a vector. * Adds the location by a vector.
* *
* @see Vector
* @param vec Vector to use * @param vec Vector to use
* @return the same location * @return the same location
* @see Vector
*/ */
public Location add(Vector vec) { public Location add(Vector vec) {
this.x += vec.getX(); this.x += vec.getX();
@ -191,11 +237,11 @@ public class Location implements Cloneable {
/** /**
* Adds the location by another. Not world-aware. * Adds the location by another. Not world-aware.
* *
* @see Vector
* @param x X coordinate * @param x X coordinate
* @param y Y coordinate * @param y Y coordinate
* @param z Z coordinate * @param z Z coordinate
* @return the same location * @return the same location
* @see Vector
*/ */
public Location add(double x, double y, double z) { public Location add(double x, double y, double z) {
this.x += x; this.x += x;
@ -207,10 +253,10 @@ public class Location implements Cloneable {
/** /**
* Subtracts the location by another. * Subtracts the location by another.
* *
* @see Vector
* @param vec The other location * @param vec The other location
* @return the same location * @return the same location
* @throws IllegalArgumentException for differing worlds * @throws IllegalArgumentException for differing worlds
* @see Vector
*/ */
public Location subtract(Location vec) { public Location subtract(Location vec) {
if (vec == null || vec.getWorld() != getWorld()) { if (vec == null || vec.getWorld() != getWorld()) {
@ -226,9 +272,9 @@ public class Location implements Cloneable {
/** /**
* Subtracts the location by a vector. * Subtracts the location by a vector.
* *
* @see Vector
* @param vec The vector to use * @param vec The vector to use
* @return the same location * @return the same location
* @see Vector
*/ */
public Location subtract(Vector vec) { public Location subtract(Vector vec) {
this.x -= vec.getX(); this.x -= vec.getX();
@ -241,11 +287,11 @@ public class Location implements Cloneable {
* Subtracts the location by another. Not world-aware and * Subtracts the location by another. Not world-aware and
* orientation independent. * orientation independent.
* *
* @see Vector
* @param x X coordinate * @param x X coordinate
* @param y Y coordinate * @param y Y coordinate
* @param z Z coordinate * @param z Z coordinate
* @return the same location * @return the same location
* @see Vector
*/ */
public Location subtract(double x, double y, double z) { public Location subtract(double x, double y, double z) {
this.x -= x; this.x -= x;
@ -348,7 +394,7 @@ public class Location implements Cloneable {
* Constructs a new {@link Vector} based on this Location * Constructs a new {@link Vector} based on this Location
* *
* @return New Vector containing the coordinates represented by this * @return New Vector containing the coordinates represented by this
* Location * Location
*/ */
public Vector toVector() { public Vector toVector() {
return new Vector(x, y, z); return new Vector(x, y, z);
@ -367,58 +413,12 @@ public class Location implements Cloneable {
NumberConversions.checkFinite(yaw, "yaw not finite"); NumberConversions.checkFinite(yaw, "yaw not finite");
} }
/** @Override
* Safely converts a double (location coordinate) to an int (block public String toString() {
* coordinate) return "Location{" + "world=" + world + ",x=" + x + ",y=" + y + ",z=" + z + ",pitch=" + pitch + ",yaw=" + yaw + "}";
*
* @param loc Precise coordinate
* @return Block coordinate
*/
public static int locToBlock(double loc) {
return NumberConversions.floor(loc);
} }
/** @Override
* Normalizes the given yaw angle to a value between <code>+/-180</code>
* 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 <code>+/-90</code>
* 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
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (obj == null) { if (obj == null) {
return false; return false;
@ -445,10 +445,7 @@ public class Location implements Cloneable {
if (Float.floatToIntBits(this.pitch) != Float.floatToIntBits(other.pitch)) { if (Float.floatToIntBits(this.pitch) != Float.floatToIntBits(other.pitch)) {
return false; return false;
} }
if (Float.floatToIntBits(this.yaw) != Float.floatToIntBits(other.yaw)) { return Float.floatToIntBits(this.yaw) == Float.floatToIntBits(other.yaw);
return false;
}
return true;
} }
@Override @Override

View File

@ -1,12 +1,12 @@
package com.loohp.limbo.location; package com.loohp.limbo.location;
import java.util.Random;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.primitives.Doubles; import com.google.common.primitives.Doubles;
import com.loohp.limbo.utils.NumberConversions; import com.loohp.limbo.utils.NumberConversions;
import com.loohp.limbo.world.World; import com.loohp.limbo.world.World;
import java.util.Random;
/** /**
* Represents a mutable vector. Because the components of Vectors are mutable, * Represents a mutable vector. Because the components of Vectors are mutable,
* storing Vectors long term may be dangerous if passing code modifies the * 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 { public class Vector implements Cloneable {
private static Random random = new Random();
/** /**
* Threshold for fuzzy equals(). * Threshold for fuzzy equals().
*/ */
private static final double epsilon = 0.000001; private static final double epsilon = 0.000001;
private static final Random random = new Random();
protected double x; protected double x;
protected double y; protected double y;
protected double z; protected double z;
@ -74,6 +72,47 @@ public class Vector implements Cloneable {
this.z = z; 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 * Adds a vector to this one
* *
@ -400,7 +439,7 @@ public class Vector implements Cloneable {
* Matrix</a>. * Matrix</a>.
* *
* @param angle the angle to rotate the vector about. This angle is passed * @param angle the angle to rotate the vector about. This angle is passed
* in radians * in radians
* @return the same vector * @return the same vector
*/ */
public Vector rotateAroundX(double angle) { public Vector rotateAroundX(double angle) {
@ -421,7 +460,7 @@ public class Vector implements Cloneable {
* Matrix</a>. * Matrix</a>.
* *
* @param angle the angle to rotate the vector about. This angle is passed * @param angle the angle to rotate the vector about. This angle is passed
* in radians * in radians
* @return the same vector * @return the same vector
*/ */
public Vector rotateAroundY(double angle) { public Vector rotateAroundY(double angle) {
@ -442,7 +481,7 @@ public class Vector implements Cloneable {
* Matrix</a>. * Matrix</a>.
* *
* @param angle the angle to rotate the vector about. This angle is passed * @param angle the angle to rotate the vector about. This angle is passed
* in radians * in radians
* @return the same vector * @return the same vector
*/ */
public Vector rotateAroundZ(double angle) { 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 * with the scaling of a non-unit axis vector, you can use
* {@link Vector#rotateAroundNonUnitAxis(Vector, double)}. * {@link Vector#rotateAroundNonUnitAxis(Vector, double)}.
* *
* @param axis the axis to rotate the vector around. If the passed vector is * @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 * not of length 1, it gets copied and normalized before using it for the
* rotation. Please use {@link Vector#normalize()} on the instance before * rotation. Please use {@link Vector#normalize()} on the instance before
* passing it to this method * passing it to this method
* @param angle the angle to rotate the vector around the axis * @param angle the angle to rotate the vector around the axis
* @return the same vector * @return the same vector
* @throws IllegalArgumentException if the provided axis vector instance is * @throws IllegalArgumentException if the provided axis vector instance is
* null * null
*/ */
public Vector rotateAroundAxis(Vector axis, double angle) throws IllegalArgumentException { public Vector rotateAroundAxis(Vector axis, double angle) throws IllegalArgumentException {
Preconditions.checkArgument(axis != null, "The provided axis vector was null"); 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 * about the scaling of the vector, use
* {@link Vector#rotateAroundAxis(Vector, double)} * {@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 * @param angle the angle to rotate the vector around the axis
* @return the same vector * @return the same vector
* @throws IllegalArgumentException if the provided axis vector instance is * @throws IllegalArgumentException if the provided axis vector instance is
* null * null
*/ */
public Vector rotateAroundNonUnitAxis(Vector axis, double angle) throws IllegalArgumentException { public Vector rotateAroundNonUnitAxis(Vector axis, double angle) throws IllegalArgumentException {
Preconditions.checkArgument(axis != null, "The provided axis vector was null"); Preconditions.checkArgument(axis != null, "The provided axis vector was null");
@ -533,54 +572,6 @@ public class Vector implements Cloneable {
return x; 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. * Set the X component.
* *
@ -614,6 +605,25 @@ public class Vector implements Cloneable {
return this; 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. * Set the Y component.
* *
@ -647,6 +657,25 @@ public class Vector implements Cloneable {
return this; 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. * Set the Z component.
* *
@ -680,6 +709,16 @@ public class Vector implements Cloneable {
return this; 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. * Checks to see if two objects are equal.
* <p> * <p>
@ -713,6 +752,15 @@ public class Vector implements Cloneable {
return hash; 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. * Get a new vector.
* *
@ -749,7 +797,7 @@ public class Vector implements Cloneable {
* Gets a Location version of this vector. * Gets a Location version of this vector.
* *
* @param world The world to link the location to. * @param world The world to link the location to.
* @param yaw The desired yaw. * @param yaw The desired yaw.
* @param pitch The desired pitch. * @param pitch The desired pitch.
* @return the location * @return the location
*/ */
@ -757,15 +805,6 @@ public class Vector implements Cloneable {
return new Location(world, x, y, z, yaw, pitch); 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. * Check if each component of this Vector is finite.
* *
@ -777,47 +816,6 @@ public class Vector implements Cloneable {
NumberConversions.checkFinite(z, "z not finite"); 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 @Override
public Map<String, Object> serialize() { public Map<String, Object> serialize() {

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,10 @@
package com.loohp.limbo.permissions; 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.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
@ -7,63 +12,60 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; 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 { public class PermissionsManager {
private Map<String, List<String>> users; private final Map<String, List<String>> users;
private Map<String, List<String>> permissions; private final Map<String, List<String>> permissions;
public PermissionsManager() { public PermissionsManager() {
users = new HashMap<>(); users = new HashMap<>();
permissions = new HashMap<>(); permissions = new HashMap<>();
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void loadDefaultPermissionFile(File file) throws IOException { public void loadDefaultPermissionFile(File file) throws IOException {
FileConfiguration config = new FileConfiguration(file); FileConfiguration config = new FileConfiguration(file);
permissions.put("default", new ArrayList<>()); permissions.put("default", new ArrayList<>());
try { try {
for (Object obj : config.get("groups", Map.class).keySet()) { for (Object obj : config.get("groups", Map.class).keySet()) {
String key = (String) obj; String key = (String) obj;
List<String> nodes = new ArrayList<>(); List<String> nodes = new ArrayList<>();
nodes.addAll(config.get("groups." + key, List.class)); nodes.addAll(config.get("groups." + key, List.class));
permissions.put(key, nodes); permissions.put(key, nodes);
} }
} catch (Exception e) {} } catch (Exception e) {
try { }
for (Object obj : config.get("players", Map.class).keySet()) { try {
String key = (String) obj; for (Object obj : config.get("players", Map.class).keySet()) {
List<String> groups = new ArrayList<>(); String key = (String) obj;
groups.addAll(config.get("players." + key, List.class)); List<String> groups = new ArrayList<>();
users.put(key, groups); groups.addAll(config.get("players." + key, List.class));
} users.put(key, groups);
} catch (Exception e) {} }
} } catch (Exception e) {
}
}
public boolean hasPermission(CommandSender sender, String permission) { public boolean hasPermission(CommandSender sender, String permission) {
if (sender instanceof Console) { if (sender instanceof Console) {
return true; return true;
} else if (sender instanceof Player) { } else if (sender instanceof Player) {
Player player = (Player) sender; 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)))) { if (users.get(player.getName()) != null && users.get(player.getName()).stream().anyMatch(each -> permissions.get(each).stream().anyMatch(node -> node.equalsIgnoreCase(permission)))) {
return true; return true;
} else { } else {
return permissions.get("default").stream().anyMatch(node -> node.equalsIgnoreCase(permission)); return permissions.get("default").stream().anyMatch(node -> node.equalsIgnoreCase(permission));
} }
} }
return false; return false;
} }
public Map<String, List<String>> getUsers() { public Map<String, List<String>> getUsers() {
return users; return users;
} }
public Map<String, List<String>> getPermissions() { public Map<String, List<String>> getPermissions() {
return permissions; return permissions;
} }
} }

View File

@ -1,147 +1,142 @@
package com.loohp.limbo.player; package com.loohp.limbo.player;
import java.io.IOException;
import java.util.UUID;
import com.loohp.limbo.Limbo; 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.commands.CommandSender;
import com.loohp.limbo.entity.DataWatcher; 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.WatchableField;
import com.loohp.limbo.entity.DataWatcher.WatchableObjectType; 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.location.Location;
import com.loohp.limbo.server.ClientConnection;
import com.loohp.limbo.server.packets.*;
import com.loohp.limbo.utils.GameMode; import com.loohp.limbo.utils.GameMode;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.chat.ComponentSerializer; import net.md_5.bungee.chat.ComponentSerializer;
import java.io.IOException;
import java.util.UUID;
public class Player extends LivingEntity implements CommandSender { public class Player extends LivingEntity implements CommandSender {
public final ClientConnection clientConnection; public final ClientConnection clientConnection;
public final PlayerInteractManager playerInteractManager; public final PlayerInteractManager playerInteractManager;
protected final String username; protected final String username;
protected GameMode gamemode; protected GameMode gamemode;
protected DataWatcher watcher; protected DataWatcher watcher;
protected byte selectedSlot; protected byte selectedSlot;
@WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.FLOAT) @WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.FLOAT)
protected float additionalHearts = 0.0F; protected float additionalHearts = 0.0F;
@WatchableField(MetadataIndex = 15, WatchableObjectType = WatchableObjectType.VARINT) @WatchableField(MetadataIndex = 15, WatchableObjectType = WatchableObjectType.VARINT)
protected int score = 0; protected int score = 0;
@WatchableField(MetadataIndex = 16, WatchableObjectType = WatchableObjectType.BYTE) @WatchableField(MetadataIndex = 16, WatchableObjectType = WatchableObjectType.BYTE)
protected byte skinLayers = 0; protected byte skinLayers = 0;
@WatchableField(MetadataIndex = 17, WatchableObjectType = WatchableObjectType.BYTE) @WatchableField(MetadataIndex = 17, WatchableObjectType = WatchableObjectType.BYTE)
protected byte mainHand = 1; protected byte mainHand = 1;
//@WatchableField(MetadataIndex = 18, WatchableObjectType = WatchableObjectType.NBT) //@WatchableField(MetadataIndex = 18, WatchableObjectType = WatchableObjectType.NBT)
//protected Entity leftShoulder = null; //protected Entity leftShoulder = null;
//@WatchableField(MetadataIndex = 19, WatchableObjectType = WatchableObjectType.NBT) //@WatchableField(MetadataIndex = 19, WatchableObjectType = WatchableObjectType.NBT)
//protected Entity rightShoulder = null; //protected Entity rightShoulder = null;
public Player(ClientConnection clientConnection, String username, UUID uuid, int entityId, Location location, PlayerInteractManager playerInteractManager) throws IllegalArgumentException, IllegalAccessException { 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()); super(EntityType.PLAYER, entityId, uuid, location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
this.clientConnection = clientConnection; this.clientConnection = clientConnection;
this.username = username; this.username = username;
this.entityId = entityId; this.entityId = entityId;
this.playerInteractManager = playerInteractManager; this.playerInteractManager = playerInteractManager;
this.playerInteractManager.setPlayer(this); this.playerInteractManager.setPlayer(this);
this.watcher = new DataWatcher(this); this.watcher = new DataWatcher(this);
this.watcher.update(); this.watcher.update();
} }
public byte getSelectedSlot() { public byte getSelectedSlot() {
return selectedSlot; return selectedSlot;
} }
public void setSelectedSlot(byte slot) { public void setSelectedSlot(byte slot) {
if(slot == selectedSlot) if (slot == selectedSlot)
return; return;
try { try {
PacketPlayOutHeldItemChange state = new PacketPlayOutHeldItemChange(slot); PacketPlayOutHeldItemChange state = new PacketPlayOutHeldItemChange(slot);
clientConnection.sendPacket(state); clientConnection.sendPacket(state);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
this.selectedSlot = slot; this.selectedSlot = slot;
} }
public GameMode getGamemode() { public GameMode getGamemode() {
return gamemode; return gamemode;
} }
public void setGamemode(GameMode gamemode) { public void setGamemode(GameMode gamemode) {
if (!this.gamemode.equals(gamemode)) { if (!this.gamemode.equals(gamemode)) {
try { try {
PacketPlayOutGameState state = new PacketPlayOutGameState(3, gamemode.getId()); PacketPlayOutGameState state = new PacketPlayOutGameState(3, gamemode.getId());
clientConnection.sendPacket(state); clientConnection.sendPacket(state);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
this.gamemode = gamemode; this.gamemode = gamemode;
} }
@Deprecated @Deprecated
protected void setEntityId(int entityId) { protected void setEntityId(int entityId) {
this.entityId = entityId; this.entityId = entityId;
} }
public float getAdditionalHearts() { public float getAdditionalHearts() {
return additionalHearts; return additionalHearts;
} }
public void setAdditionalHearts(float additionalHearts) { public void setAdditionalHearts(float additionalHearts) {
this.additionalHearts = additionalHearts; this.additionalHearts = additionalHearts;
} }
public int getScore() { public int getScore() {
return score; return score;
} }
public void setScore(int score) { public void setScore(int score) {
this.score = score; this.score = score;
} }
public byte getSkinLayers() { public byte getSkinLayers() {
return skinLayers; return skinLayers;
} }
public void setSkinLayers(byte skinLayers) { public void setSkinLayers(byte skinLayers) {
this.skinLayers = skinLayers; this.skinLayers = skinLayers;
} }
public byte getMainHand() { public byte getMainHand() {
return mainHand; return mainHand;
} }
public void setMainHand(byte mainHand) { public void setMainHand(byte mainHand) {
this.mainHand = mainHand; this.mainHand = mainHand;
} }
@Override @Override
public DataWatcher getDataWatcher() { public DataWatcher getDataWatcher() {
return watcher; return watcher;
} }
@Override @Override
public boolean isValid() { public boolean isValid() {
return Limbo.getInstance().getPlayers().contains(this); return Limbo.getInstance().getPlayers().contains(this);
} }
@Override @Override
public void remove() { public void remove() {
} }
/* /*
public Entity getLeftShoulder() { public Entity getLeftShoulder() {
@ -161,101 +156,101 @@ public class Player extends LivingEntity implements CommandSender {
} }
*/ */
@Override @Override
public String getName() { public String getName() {
return username; return username;
} }
@Override @Override
public boolean hasPermission(String permission) { public boolean hasPermission(String permission) {
return Limbo.getInstance().getPermissionsManager().hasPermission(this, permission); return Limbo.getInstance().getPermissionsManager().hasPermission(this, permission);
} }
@Override @Override
public void teleport(Location location) { public void teleport(Location location) {
PlayerTeleportEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerTeleportEvent(this, getLocation(), location)); PlayerTeleportEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerTeleportEvent(this, getLocation(), location));
if (!event.isCancelled()) { if (!event.isCancelled()) {
location = event.getTo(); location = event.getTo();
super.teleport(location); super.teleport(location);
try { try {
if (!world.equals(location.getWorld())) { if (!world.equals(location.getWorld())) {
PacketPlayOutRespawn respawn = new PacketPlayOutRespawn(location.getWorld(), Limbo.getInstance().getDimensionRegistry().getCodec(), 0, gamemode, false, false, true); PacketPlayOutRespawn respawn = new PacketPlayOutRespawn(location.getWorld(), Limbo.getInstance().getDimensionRegistry().getCodec(), 0, gamemode, false, false, true);
clientConnection.sendPacket(respawn); clientConnection.sendPacket(respawn);
} }
PacketPlayOutPositionAndLook positionLook = new PacketPlayOutPositionAndLook(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch(), 1); PacketPlayOutPositionAndLook positionLook = new PacketPlayOutPositionAndLook(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch(), 1);
clientConnection.sendPacket(positionLook); clientConnection.sendPacket(positionLook);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
protected void setLocation(Location location) { protected void setLocation(Location location) {
super.teleport(location); super.teleport(location);
} }
public void sendMessage(String message, UUID uuid) { public void sendMessage(String message, UUID uuid) {
sendMessage(TextComponent.fromLegacyText(message), uuid); sendMessage(TextComponent.fromLegacyText(message), uuid);
} }
public void sendMessage(BaseComponent component, UUID uuid) { public void sendMessage(BaseComponent component, UUID uuid) {
sendMessage(new BaseComponent[] { component }, uuid); sendMessage(new BaseComponent[]{component}, uuid);
} }
@Override @Override
public void sendMessage(BaseComponent[] component, UUID uuid) { public void sendMessage(BaseComponent[] component, UUID uuid) {
try { try {
PacketPlayOutChat chat = new PacketPlayOutChat(ComponentSerializer.toString(component), 0, uuid); PacketPlayOutChat chat = new PacketPlayOutChat(ComponentSerializer.toString(component), 0, uuid);
clientConnection.sendPacket(chat); clientConnection.sendPacket(chat);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public void sendMessage(String message) { public void sendMessage(String message) {
sendMessage(TextComponent.fromLegacyText(message)); sendMessage(TextComponent.fromLegacyText(message));
} }
public void sendMessage(BaseComponent component) { public void sendMessage(BaseComponent component) {
sendMessage(new BaseComponent[] { component }); sendMessage(new BaseComponent[]{component});
} }
@Override @Override
public void sendMessage(BaseComponent[] component) { public void sendMessage(BaseComponent[] component) {
try { try {
PacketPlayOutChat chat = new PacketPlayOutChat(ComponentSerializer.toString(component), 0, new UUID(0, 0)); PacketPlayOutChat chat = new PacketPlayOutChat(ComponentSerializer.toString(component), 0, new UUID(0, 0));
clientConnection.sendPacket(chat); clientConnection.sendPacket(chat);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public void disconnect() { public void disconnect() {
disconnect("Disconnected!"); disconnect("Disconnected!");
} }
public void disconnect(String reason) { public void disconnect(String reason) {
disconnect(TextComponent.fromLegacyText(reason)); disconnect(TextComponent.fromLegacyText(reason));
} }
public void disconnect(BaseComponent reason) { public void disconnect(BaseComponent reason) {
disconnect(new BaseComponent[] {reason}); disconnect(new BaseComponent[]{reason});
} }
public void disconnect(BaseComponent[] reason) { public void disconnect(BaseComponent[] reason) {
clientConnection.disconnect(reason); clientConnection.disconnect(reason);
} }
public void chat(String message) { public void chat(String message) {
String prefix = "<" + username + "> "; String prefix = "<" + username + "> ";
PlayerChatEvent event = (PlayerChatEvent) Limbo.getInstance().getEventsManager().callEvent(new PlayerChatEvent(this, prefix, message, false)); PlayerChatEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerChatEvent(this, prefix, message, false));
if (!event.isCancelled()) { if (!event.isCancelled()) {
String chat = event.getPrefix() + event.getMessage(); String chat = event.getPrefix() + event.getMessage();
Limbo.getInstance().getConsole().sendMessage(chat); Limbo.getInstance().getConsole().sendMessage(chat);
for (Player each : Limbo.getInstance().getPlayers()) { for (Player each : Limbo.getInstance().getPlayers()) {
each.sendMessage(chat, uuid); each.sendMessage(chat, uuid);
} }
} }
} }
} }

View File

@ -1,135 +1,123 @@
package com.loohp.limbo.player; 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.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.entity.Entity;
import com.loohp.limbo.location.Location; import com.loohp.limbo.location.Location;
import com.loohp.limbo.server.packets.*;
import com.loohp.limbo.world.World; import com.loohp.limbo.world.World;
import net.querz.mca.Chunk; 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 { public class PlayerInteractManager {
private Player player; private Player player;
private Set<Entity> entities; private Set<Entity> entities;
private Map<Chunk, World> chunks; private Map<Chunk, World> chunks;
public PlayerInteractManager() { public PlayerInteractManager() {
this.player = null; this.player = null;
this.entities = new HashSet<>(); this.entities = new HashSet<>();
this.chunks = new HashMap<>(); this.chunks = new HashMap<>();
} }
protected void setPlayer(Player player) { public Player getPlayer() {
if (this.player == null) { return player;
this.player = player; }
} else {
throw new RuntimeException("Player in PlayerInteractManager cannot be changed once created");
}
}
public Player getPlayer() { protected void setPlayer(Player player) {
return 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 { public void update() throws IOException {
int viewDistanceChunks = Limbo.getInstance().getServerProperties().getViewDistance(); int viewDistanceChunks = Limbo.getInstance().getServerProperties().getViewDistance();
int viewDistanceBlocks = viewDistanceChunks << 4; int viewDistanceBlocks = viewDistanceChunks << 4;
Location location = player.getLocation(); Location location = player.getLocation();
Set<Entity> entitiesInRange = player.getWorld().getEntities().stream().filter(each -> each.getLocation().distanceSquared(location) < viewDistanceBlocks * viewDistanceBlocks).collect(Collectors.toSet()); Set<Entity> entitiesInRange = player.getWorld().getEntities().stream().filter(each -> each.getLocation().distanceSquared(location) < viewDistanceBlocks * viewDistanceBlocks).collect(Collectors.toSet());
for (Entity entity : entitiesInRange) { for (Entity entity : entitiesInRange) {
if (!entities.contains(entity)) { if (!entities.contains(entity)) {
if (entity.getType().isAlive()) { 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); 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); player.clientConnection.sendPacket(packet);
PacketPlayOutEntityMetadata meta = new PacketPlayOutEntityMetadata(entity); PacketPlayOutEntityMetadata meta = new PacketPlayOutEntityMetadata(entity);
player.clientConnection.sendPacket(meta); player.clientConnection.sendPacket(meta);
} else { } 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); 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); player.clientConnection.sendPacket(packet);
PacketPlayOutEntityMetadata meta = new PacketPlayOutEntityMetadata(entity); PacketPlayOutEntityMetadata meta = new PacketPlayOutEntityMetadata(entity);
player.clientConnection.sendPacket(meta); player.clientConnection.sendPacket(meta);
} }
} }
} }
List<Integer> ids = new ArrayList<>(); List<Integer> ids = new ArrayList<>();
for (Entity entity : entities) { for (Entity entity : entities) {
if (!entitiesInRange.contains(entity)) { if (!entitiesInRange.contains(entity)) {
ids.add(entity.getEntityId()); ids.add(entity.getEntityId());
} }
} }
PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(ids.stream().mapToInt(each -> each).toArray()); PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(ids.stream().mapToInt(each -> each).toArray());
player.clientConnection.sendPacket(packet); player.clientConnection.sendPacket(packet);
entities = entitiesInRange; entities = entitiesInRange;
int playerChunkX = (int) location.getX() >> 4; int playerChunkX = (int) location.getX() >> 4;
int playerChunkZ = (int) location.getZ() >> 4; int playerChunkZ = (int) location.getZ() >> 4;
World world = location.getWorld(); World world = location.getWorld();
Set<Chunk> chunksInRange = new HashSet<>(); Set<Chunk> chunksInRange = new HashSet<>();
for (int x = playerChunkX - viewDistanceChunks; x < playerChunkX + viewDistanceChunks; x++) { for (int x = playerChunkX - viewDistanceChunks; x < playerChunkX + viewDistanceChunks; x++) {
for (int z = playerChunkZ - viewDistanceChunks; z < playerChunkZ + viewDistanceChunks; z++) { for (int z = playerChunkZ - viewDistanceChunks; z < playerChunkZ + viewDistanceChunks; z++) {
Chunk chunk = world.getChunkAt(x, z); Chunk chunk = world.getChunkAt(x, z);
if (chunk != null) { if (chunk != null) {
chunksInRange.add(chunk); chunksInRange.add(chunk);
} }
} }
} }
for (Entry<Chunk, World> entry : chunks.entrySet()) { for (Entry<Chunk, World> entry : chunks.entrySet()) {
Chunk chunk = entry.getKey(); Chunk chunk = entry.getKey();
if (location.getWorld().getChunkXZ(chunk) == null) { if (location.getWorld().getChunkXZ(chunk) == null) {
World world0 = entry.getValue(); World world0 = entry.getValue();
int[] chunkPos = world0.getChunkXZ(chunk); int[] chunkPos = world0.getChunkXZ(chunk);
PacketPlayOutUnloadChunk packet0 = new PacketPlayOutUnloadChunk(chunkPos[0], chunkPos[1]); PacketPlayOutUnloadChunk packet0 = new PacketPlayOutUnloadChunk(chunkPos[0], chunkPos[1]);
player.clientConnection.sendPacket(packet0); player.clientConnection.sendPacket(packet0);
} }
} }
for (Chunk chunk : chunksInRange) { for (Chunk chunk : chunksInRange) {
if (!chunks.containsKey(chunk)) { if (!chunks.containsKey(chunk)) {
int[] chunkPos = world.getChunkXZ(chunk); int[] chunkPos = world.getChunkXZ(chunk);
PacketPlayOutMapChunk packet0 = new PacketPlayOutMapChunk(chunkPos[0], chunkPos[1], chunk, world.getEnvironment()); PacketPlayOutMapChunk packet0 = new PacketPlayOutMapChunk(chunkPos[0], chunkPos[1], chunk, world.getEnvironment());
player.clientConnection.sendPacket(packet0); player.clientConnection.sendPacket(packet0);
List<Byte[]> blockChunk = world.getLightEngineBlock().getBlockLightBitMask(chunkPos[0], chunkPos[1]); List<Byte[]> blockChunk = world.getLightEngineBlock().getBlockLightBitMask(chunkPos[0], chunkPos[1]);
if (blockChunk == null) { if (blockChunk == null) {
blockChunk = new ArrayList<>(); blockChunk = new ArrayList<>();
} }
List<Byte[]> skyChunk = null; List<Byte[]> skyChunk = null;
if (world.hasSkyLight()) { if (world.hasSkyLight()) {
skyChunk = world.getLightEngineSky().getSkyLightBitMask(chunkPos[0], chunkPos[1]); skyChunk = world.getLightEngineSky().getSkyLightBitMask(chunkPos[0], chunkPos[1]);
} }
if (skyChunk == null) { if (skyChunk == null) {
skyChunk = new ArrayList<>(); skyChunk = new ArrayList<>();
} }
PacketPlayOutLightUpdate chunkdata = new PacketPlayOutLightUpdate(chunkPos[0], chunkPos[1], true, skyChunk, blockChunk); PacketPlayOutLightUpdate chunkdata = new PacketPlayOutLightUpdate(chunkPos[0], chunkPos[1], true, skyChunk, blockChunk);
player.clientConnection.sendPacket(chunkdata); player.clientConnection.sendPacket(chunkdata);
} }
} }
chunks = chunksInRange.stream().collect(Collectors.toMap(each -> each, each -> world)); chunks = chunksInRange.stream().collect(Collectors.toMap(each -> each, each -> world));
} }
} }

View File

@ -6,26 +6,27 @@ import com.loohp.limbo.utils.GameMode;
@Deprecated @Deprecated
public class Unsafe { public class Unsafe {
private Unsafe() {} private Unsafe() {
}
@Deprecated @Deprecated
public void a(Player a, GameMode b) { public void a(Player a, GameMode b) {
a.gamemode = b; a.gamemode = b;
} }
@Deprecated @Deprecated
public void a(Player a, int b) { public void a(Player a, int b) {
a.setEntityId(b); a.setEntityId(b);
} }
@Deprecated @Deprecated
public void a(Player a, Location b) { public void a(Player a, Location b) {
a.setLocation(b); a.setLocation(b);
} }
@Deprecated @Deprecated
public void a(Player a, byte b) { public void a(Player a, byte b) {
a.selectedSlot = b; a.selectedSlot = b;
} }
} }

View File

@ -1,54 +1,54 @@
package com.loohp.limbo.plugins; package com.loohp.limbo.plugins;
import java.io.File;
import com.loohp.limbo.Limbo; import com.loohp.limbo.Limbo;
import com.loohp.limbo.file.FileConfiguration; import com.loohp.limbo.file.FileConfiguration;
import java.io.File;
public class LimboPlugin { public class LimboPlugin {
private String name; private String name;
private File dataFolder; private File dataFolder;
private PluginInfo info; private PluginInfo info;
private File pluginJar; private File pluginJar;
protected final void setInfo(FileConfiguration file, File pluginJar) { protected final void setInfo(FileConfiguration file, File pluginJar) {
this.info = new PluginInfo(file); this.info = new PluginInfo(file);
this.name = info.getName(); this.name = info.getName();
this.dataFolder = new File(Limbo.getInstance().getPluginFolder(), name); this.dataFolder = new File(Limbo.getInstance().getPluginFolder(), name);
this.pluginJar = pluginJar; this.pluginJar = pluginJar;
} }
protected final File getPluginJar() { protected final File getPluginJar() {
return pluginJar; return pluginJar;
} }
public void onLoad() { public void onLoad() {
} }
public void onEnable() { public void onEnable() {
} }
public void onDisable() { public void onDisable() {
} }
public final String getName() { public final String getName() {
return name; return name;
} }
public final File getDataFolder() { public final File getDataFolder() {
return new File(dataFolder.getAbsolutePath()); return new File(dataFolder.getAbsolutePath());
} }
public final PluginInfo getInfo() { public final PluginInfo getInfo() {
return info; return info;
} }
public final Limbo getServer() { public final Limbo getServer() {
return Limbo.getInstance(); return Limbo.getInstance();
} }
} }

View File

@ -4,38 +4,38 @@ import com.loohp.limbo.file.FileConfiguration;
public class PluginInfo { public class PluginInfo {
private String name; private final String name;
private String description; private final String description;
private String author; private final String author;
private String version; private final String version;
private String main; private final String main;
public PluginInfo(FileConfiguration file) { public PluginInfo(FileConfiguration file) {
name = file.get("name", String.class); name = file.get("name", String.class);
description = file.get("description", String.class) == null ? "" : file.get("description", String.class); description = file.get("description", String.class) == null ? "" : file.get("description", String.class);
author = file.get("author", String.class); author = file.get("author", String.class);
version = file.get("version", String.class); version = file.get("version", String.class);
main = file.get("main", String.class); main = file.get("main", String.class);
} }
public String getName() { public String getName() {
return name; return name;
} }
public String getDescription() { public String getDescription() {
return description; return description;
} }
public String getAuthor() { public String getAuthor() {
return author; return author;
} }
public String getVersion() { public String getVersion() {
return version; return version;
} }
public String getMainClass() { public String getMainClass() {
return main; return main;
} }
} }

View File

@ -1,139 +1,135 @@
package com.loohp.limbo.plugins; 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.Limbo;
import com.loohp.limbo.commands.CommandExecutor; import com.loohp.limbo.commands.CommandExecutor;
import com.loohp.limbo.commands.CommandSender; import com.loohp.limbo.commands.CommandSender;
import com.loohp.limbo.commands.TabCompletor; import com.loohp.limbo.commands.TabCompletor;
import com.loohp.limbo.file.FileConfiguration; 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 { public class PluginManager {
private Map<String, LimboPlugin> plugins; private final Map<String, LimboPlugin> plugins;
private List<Executor> executors; private final List<Executor> executors;
private File pluginFolder; private final File pluginFolder;
public PluginManager(File pluginFolder) { public PluginManager(File pluginFolder) {
this.pluginFolder = pluginFolder; this.pluginFolder = pluginFolder;
this.executors = new ArrayList<>(); this.executors = new ArrayList<>();
this.plugins = new LinkedHashMap<>(); this.plugins = new LinkedHashMap<>();
} }
protected void loadPlugins() { protected void loadPlugins() {
for (File file : pluginFolder.listFiles()) { for (File file : pluginFolder.listFiles()) {
if (file.isFile() && file.getName().endsWith(".jar")) { if (file.isFile() && file.getName().endsWith(".jar")) {
boolean found = false; boolean found = false;
try (ZipInputStream zip = new ZipInputStream(new FileInputStream(file))) { try (ZipInputStream zip = new ZipInputStream(new FileInputStream(file))) {
while (true) { while (true) {
ZipEntry entry = zip.getNextEntry(); ZipEntry entry = zip.getNextEntry();
if (entry == null) { if (entry == null) {
break; break;
} }
String name = entry.getName(); String name = entry.getName();
if (name.endsWith("plugin.yml") || name.endsWith("limbo.yml")) { if (name.endsWith("plugin.yml") || name.endsWith("limbo.yml")) {
found = true; found = true;
FileConfiguration pluginYaml = new FileConfiguration(zip); FileConfiguration pluginYaml = new FileConfiguration(zip);
String main = pluginYaml.get("main", String.class); String main = pluginYaml.get("main", String.class);
String pluginName = pluginYaml.get("name", String.class); String pluginName = pluginYaml.get("name", String.class);
if (plugins.containsKey(pluginName)) { if (plugins.containsKey(pluginName)) {
System.err.println("Ambiguous plugin name in " + file.getName() + " with the plugin \"" + plugins.get(pluginName).getClass().getName() + "\""); System.err.println("Ambiguous plugin name in " + file.getName() + " with the plugin \"" + plugins.get(pluginName).getClass().getName() + "\"");
break; break;
} }
URLClassLoader child = new URLClassLoader(new URL[] {file.toURI().toURL()}, Limbo.getInstance().getClass().getClassLoader()); URLClassLoader child = new URLClassLoader(new URL[]{file.toURI().toURL()}, Limbo.getInstance().getClass().getClassLoader());
Class<?> clazz = Class.forName(main, true, child); Class<?> clazz = Class.forName(main, true, child);
LimboPlugin plugin = (LimboPlugin) clazz.getDeclaredConstructor().newInstance(); LimboPlugin plugin = (LimboPlugin) clazz.getDeclaredConstructor().newInstance();
plugin.setInfo(pluginYaml, file); plugin.setInfo(pluginYaml, file);
plugins.put(plugin.getName(), plugin); plugins.put(plugin.getName(), plugin);
plugin.onLoad(); plugin.onLoad();
Limbo.getInstance().getConsole().sendMessage("Loading plugin " + file.getName() + " " + plugin.getInfo().getVersion() + " by " + plugin.getInfo().getAuthor()); Limbo.getInstance().getConsole().sendMessage("Loading plugin " + file.getName() + " " + plugin.getInfo().getVersion() + " by " + plugin.getInfo().getAuthor());
break; break;
} }
} }
} catch (Exception e) { } catch (Exception e) {
System.err.println("Unable to load plugin \"" + file.getName() + "\""); System.err.println("Unable to load plugin \"" + file.getName() + "\"");
e.printStackTrace(); e.printStackTrace();
} }
if (!found) { if (!found) {
System.err.println("Jar file " + file.getName() + " has no plugin.yml!"); System.err.println("Jar file " + file.getName() + " has no plugin.yml!");
} }
} }
} }
} }
public List<LimboPlugin> getPlugins() { public List<LimboPlugin> getPlugins() {
return new ArrayList<>(plugins.values()); return new ArrayList<>(plugins.values());
} }
public LimboPlugin getPlugin(String name) { public LimboPlugin getPlugin(String name) {
return plugins.get(name); return plugins.get(name);
} }
public void fireExecutors(CommandSender sender, String[] args) throws Exception { public void fireExecutors(CommandSender sender, String[] args) throws Exception {
Limbo.getInstance().getConsole().sendMessage(sender.getName() + " executed server command: /" + String.join(" ", args)); Limbo.getInstance().getConsole().sendMessage(sender.getName() + " executed server command: /" + String.join(" ", args));
for (Executor entry : executors) { for (Executor entry : executors) {
try { try {
entry.executor.execute(sender, args); entry.executor.execute(sender, args);
} catch (Exception e) { } catch (Exception e) {
System.err.println("Error while passing command \"" + args[0] + "\" to the plugin \"" + entry.plugin.getName() + "\""); System.err.println("Error while passing command \"" + args[0] + "\" to the plugin \"" + entry.plugin.getName() + "\"");
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
public List<String> getTabOptions(CommandSender sender, String[] args) { public List<String> getTabOptions(CommandSender sender, String[] args) {
List<String> options = new ArrayList<>(); List<String> options = new ArrayList<>();
for (Executor entry : executors) { for (Executor entry : executors) {
if (entry.tab.isPresent()) { if (entry.tab.isPresent()) {
try { try {
options.addAll(entry.tab.get().tabComplete(sender, args)); options.addAll(entry.tab.get().tabComplete(sender, args));
} catch (Exception e) { } catch (Exception e) {
System.err.println("Error while passing tab completion to the plugin \"" + entry.plugin.getName() + "\""); System.err.println("Error while passing tab completion to the plugin \"" + entry.plugin.getName() + "\"");
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
return options; return options;
} }
public void registerCommands(LimboPlugin plugin, CommandExecutor executor) { public void registerCommands(LimboPlugin plugin, CommandExecutor executor) {
executors.add(new Executor(plugin, executor)); executors.add(new Executor(plugin, executor));
} }
public void unregsiterAllCommands(LimboPlugin plugin) { public void unregsiterAllCommands(LimboPlugin plugin) {
executors.removeIf(each -> each.plugin.equals(plugin)); executors.removeIf(each -> each.plugin.equals(plugin));
} }
public File getPluginFolder() { public File getPluginFolder() {
return new File(pluginFolder.getAbsolutePath()); return new File(pluginFolder.getAbsolutePath());
} }
protected static class Executor { protected static class Executor {
public LimboPlugin plugin; public LimboPlugin plugin;
public CommandExecutor executor; public CommandExecutor executor;
public Optional<TabCompletor> tab; public Optional<TabCompletor> tab;
public Executor(LimboPlugin plugin, CommandExecutor executor) { public Executor(LimboPlugin plugin, CommandExecutor executor) {
this.plugin = plugin; this.plugin = plugin;
this.executor = executor; this.executor = executor;
if (executor instanceof TabCompletor) { if (executor instanceof TabCompletor) {
this.tab = Optional.of((TabCompletor) executor); this.tab = Optional.of((TabCompletor) executor);
} else { } else {
this.tab = Optional.empty(); this.tab = Optional.empty();
} }
} }
} }
} }

View File

@ -5,95 +5,95 @@ import com.loohp.limbo.plugins.LimboPlugin;
public abstract class LimboRunnable implements LimboTask { public abstract class LimboRunnable implements LimboTask {
private volatile boolean registered = false; protected volatile int taskId = -1;
protected volatile int taskId = -1; private volatile boolean registered = false;
public void cancel() { public void cancel() {
synchronized (this) { synchronized (this) {
if (registered && taskId >= 0) { if (registered && taskId >= 0) {
Limbo.getInstance().getScheduler().cancelTask(taskId); Limbo.getInstance().getScheduler().cancelTask(taskId);
} }
} }
} }
public int getTaskId() { public int getTaskId() {
if (registered && taskId >= 0) { if (registered && taskId >= 0) {
return taskId; return taskId;
} else { } else {
throw new IllegalStateException("LimboRunnable not yet scheduled"); throw new IllegalStateException("LimboRunnable not yet scheduled");
} }
} }
public LimboRunnable runTask(LimboPlugin plugin) { public LimboRunnable runTask(LimboPlugin plugin) {
synchronized (this) { synchronized (this) {
if (!registered) { if (!registered) {
taskId = Limbo.getInstance().getScheduler().runTask(plugin, this); taskId = Limbo.getInstance().getScheduler().runTask(plugin, this);
registered = true; registered = true;
return this; return this;
} else { } else {
throw new IllegalStateException("LimboRunnable already scheduled"); throw new IllegalStateException("LimboRunnable already scheduled");
} }
} }
} }
public LimboRunnable runTaskLater(LimboPlugin plugin, long delay) { public LimboRunnable runTaskLater(LimboPlugin plugin, long delay) {
synchronized (this) { synchronized (this) {
if (!registered) { if (!registered) {
taskId = Limbo.getInstance().getScheduler().runTaskLater(plugin, this, delay); taskId = Limbo.getInstance().getScheduler().runTaskLater(plugin, this, delay);
registered = true; registered = true;
return this; return this;
} else { } else {
throw new IllegalStateException("LimboRunnable already scheduled"); throw new IllegalStateException("LimboRunnable already scheduled");
} }
} }
} }
public LimboRunnable runTaskAsync(LimboPlugin plugin) { public LimboRunnable runTaskAsync(LimboPlugin plugin) {
synchronized (this) { synchronized (this) {
if (!registered) { if (!registered) {
taskId = Limbo.getInstance().getScheduler().runTaskAsync(plugin, this); taskId = Limbo.getInstance().getScheduler().runTaskAsync(plugin, this);
registered = true; registered = true;
return this; return this;
} else { } else {
throw new IllegalStateException("LimboRunnable already scheduled"); throw new IllegalStateException("LimboRunnable already scheduled");
} }
} }
} }
public LimboRunnable runTaskLaterAsync(LimboPlugin plugin, long delay) { public LimboRunnable runTaskLaterAsync(LimboPlugin plugin, long delay) {
synchronized (this) { synchronized (this) {
if (!registered) { if (!registered) {
taskId = Limbo.getInstance().getScheduler().runTaskLaterAsync(plugin, this, delay); taskId = Limbo.getInstance().getScheduler().runTaskLaterAsync(plugin, this, delay);
registered = true; registered = true;
return this; return this;
} else { } else {
throw new IllegalStateException("LimboRunnable already scheduled"); throw new IllegalStateException("LimboRunnable already scheduled");
} }
} }
} }
public LimboRunnable runTaskTimer(LimboPlugin plugin, long delay, long period) { public LimboRunnable runTaskTimer(LimboPlugin plugin, long delay, long period) {
synchronized (this) { synchronized (this) {
if (!registered) { if (!registered) {
taskId = Limbo.getInstance().getScheduler().runTaskTimer(plugin, this, delay, period); taskId = Limbo.getInstance().getScheduler().runTaskTimer(plugin, this, delay, period);
registered = true; registered = true;
return this; return this;
} else { } else {
throw new IllegalStateException("LimboRunnable already scheduled"); throw new IllegalStateException("LimboRunnable already scheduled");
} }
} }
} }
public LimboRunnable runTaskTimerAsync(LimboPlugin plugin, long delay, long period) { public LimboRunnable runTaskTimerAsync(LimboPlugin plugin, long delay, long period) {
synchronized (this) { synchronized (this) {
if (!registered) { if (!registered) {
taskId = Limbo.getInstance().getScheduler().runTaskTimerAsync(plugin, this, delay, period); taskId = Limbo.getInstance().getScheduler().runTaskTimerAsync(plugin, this, delay, period);
registered = true; registered = true;
return this; return this;
} else { } else {
throw new IllegalStateException("LimboRunnable already scheduled"); throw new IllegalStateException("LimboRunnable already scheduled");
} }
} }
} }
} }

View File

@ -1,250 +1,244 @@
package com.loohp.limbo.scheduler; 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.Limbo;
import com.loohp.limbo.plugins.LimboPlugin; import com.loohp.limbo.plugins.LimboPlugin;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
public class LimboScheduler { public class LimboScheduler {
private AtomicInteger idProvider = new AtomicInteger(0); private final AtomicInteger idProvider = new AtomicInteger(0);
private Map<Long, List<LimboSchedulerTask>> registeredTasks = new HashMap<>(); private final Map<Long, List<LimboSchedulerTask>> registeredTasks = new HashMap<>();
private Map<Integer, LimboSchedulerTask> tasksById = new HashMap<>(); private final Map<Integer, LimboSchedulerTask> tasksById = new HashMap<>();
private Set<Integer> cancelledTasks = new HashSet<>(); private final Set<Integer> cancelledTasks = new HashSet<>();
public LimboScheduler() { public LimboScheduler() {
} }
protected int nextId() { protected int nextId() {
return idProvider.getAndUpdate(id -> id >= Integer.MAX_VALUE ? 0 : id + 1); return idProvider.getAndUpdate(id -> id >= Integer.MAX_VALUE ? 0 : id + 1);
} }
public void cancelTask(int taskId) { public void cancelTask(int taskId) {
if (tasksById.containsKey(taskId)) { if (tasksById.containsKey(taskId)) {
cancelledTasks.add(taskId); cancelledTasks.add(taskId);
} }
} }
public void cancelTask(LimboPlugin plugin) { public void cancelTask(LimboPlugin plugin) {
for (LimboSchedulerTask task : tasksById.values()) { for (LimboSchedulerTask task : tasksById.values()) {
if (task.getPlugin().getName().equals(plugin.getName())) { if (task.getPlugin().getName().equals(plugin.getName())) {
cancelledTasks.add(task.getTaskId()); cancelledTasks.add(task.getTaskId());
} }
} }
} }
protected int runTask(int taskId, LimboPlugin plugin, LimboTask task) { protected int runTask(int taskId, LimboPlugin plugin, LimboTask task) {
return runTaskLater(taskId, plugin, task, 0); return runTaskLater(taskId, plugin, task, 0);
} }
public int runTask(LimboPlugin plugin, LimboTask task) { public int runTask(LimboPlugin plugin, LimboTask task) {
return runTaskLater(plugin, task, 0); return runTaskLater(plugin, task, 0);
} }
protected int runTaskLater(int taskId, LimboPlugin plugin, LimboTask task, long delay) { protected int runTaskLater(int taskId, LimboPlugin plugin, LimboTask task, long delay) {
LimboSchedulerTask st = new LimboSchedulerTask(plugin, task, taskId, LimboSchedulerTaskType.SYNC, 0); LimboSchedulerTask st = new LimboSchedulerTask(plugin, task, taskId, LimboSchedulerTaskType.SYNC, 0);
if (delay <= 0) { if (delay <= 0) {
delay = 1; delay = 1;
} }
long tick = Limbo.getInstance().getHeartBeat().getCurrentTick() + delay; long tick = Limbo.getInstance().getHeartBeat().getCurrentTick() + delay;
tasksById.put(taskId, st); tasksById.put(taskId, st);
List<LimboSchedulerTask> list = registeredTasks.get(tick); List<LimboSchedulerTask> list = registeredTasks.get(tick);
if (list == null) { if (list == null) {
list = new ArrayList<>(); list = new ArrayList<>();
registeredTasks.put(tick, list); registeredTasks.put(tick, list);
} }
list.add(st); list.add(st);
return taskId; return taskId;
} }
public int runTaskLater(LimboPlugin plugin, LimboTask task, long delay) { public int runTaskLater(LimboPlugin plugin, LimboTask task, long delay) {
return runTaskLater(nextId(), plugin, task, delay); return runTaskLater(nextId(), plugin, task, delay);
} }
protected int runTaskAsync(int taskId, LimboPlugin plugin, LimboTask task) { protected int runTaskAsync(int taskId, LimboPlugin plugin, LimboTask task) {
return runTaskLaterAsync(taskId, plugin, task, 0); return runTaskLaterAsync(taskId, plugin, task, 0);
} }
public int runTaskAsync(LimboPlugin plugin, LimboTask task) { public int runTaskAsync(LimboPlugin plugin, LimboTask task) {
return runTaskLaterAsync(plugin, task, 0); return runTaskLaterAsync(plugin, task, 0);
} }
protected int runTaskLaterAsync(int taskId, LimboPlugin plugin, LimboTask task, long delay) { protected int runTaskLaterAsync(int taskId, LimboPlugin plugin, LimboTask task, long delay) {
LimboSchedulerTask st = new LimboSchedulerTask(plugin, task, taskId, LimboSchedulerTaskType.ASYNC, 0); LimboSchedulerTask st = new LimboSchedulerTask(plugin, task, taskId, LimboSchedulerTaskType.ASYNC, 0);
if (delay <= 0) { if (delay <= 0) {
delay = 1; delay = 1;
} }
long tick = Limbo.getInstance().getHeartBeat().getCurrentTick() + delay; long tick = Limbo.getInstance().getHeartBeat().getCurrentTick() + delay;
tasksById.put(taskId, st); tasksById.put(taskId, st);
List<LimboSchedulerTask> list = registeredTasks.get(tick); List<LimboSchedulerTask> list = registeredTasks.get(tick);
if (list == null) { if (list == null) {
list = new ArrayList<>(); list = new ArrayList<>();
registeredTasks.put(tick, list); registeredTasks.put(tick, list);
} }
list.add(st); list.add(st);
return taskId; return taskId;
} }
public int runTaskLaterAsync(LimboPlugin plugin, LimboTask task, long delay) { public int runTaskLaterAsync(LimboPlugin plugin, LimboTask task, long delay) {
return runTaskLaterAsync(nextId(), plugin, task, delay); return runTaskLaterAsync(nextId(), plugin, task, delay);
} }
protected int runTaskTimer(int taskId, LimboPlugin plugin, LimboTask task, long delay, long period) { protected int runTaskTimer(int taskId, LimboPlugin plugin, LimboTask task, long delay, long period) {
LimboSchedulerTask st = new LimboSchedulerTask(plugin, task, taskId, LimboSchedulerTaskType.TIMER_SYNC, period); LimboSchedulerTask st = new LimboSchedulerTask(plugin, task, taskId, LimboSchedulerTaskType.TIMER_SYNC, period);
if (delay <= 0) { if (delay <= 0) {
delay = 1; delay = 1;
} }
if (period <= 0) { if (period <= 0) {
period = 1; period = 1;
} }
long tick = Limbo.getInstance().getHeartBeat().getCurrentTick() + delay; long tick = Limbo.getInstance().getHeartBeat().getCurrentTick() + delay;
tasksById.put(taskId, st); tasksById.put(taskId, st);
List<LimboSchedulerTask> list = registeredTasks.get(tick); List<LimboSchedulerTask> list = registeredTasks.get(tick);
if (list == null) { if (list == null) {
list = new ArrayList<>(); list = new ArrayList<>();
registeredTasks.put(tick, list); registeredTasks.put(tick, list);
} }
list.add(st); list.add(st);
return taskId; return taskId;
} }
public int runTaskTimer(LimboPlugin plugin, LimboTask task, long delay, long period) { public int runTaskTimer(LimboPlugin plugin, LimboTask task, long delay, long period) {
return runTaskTimer(nextId(), plugin, task, delay, period); return runTaskTimer(nextId(), plugin, task, delay, period);
} }
protected int runTaskTimerAsync(int taskId, LimboPlugin plugin, LimboTask task, long delay, long 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); LimboSchedulerTask st = new LimboSchedulerTask(plugin, task, taskId, LimboSchedulerTaskType.TIMER_ASYNC, period);
if (delay <= 0) { if (delay <= 0) {
delay = 1; delay = 1;
} }
if (period <= 0) { if (period <= 0) {
period = 1; period = 1;
} }
long tick = Limbo.getInstance().getHeartBeat().getCurrentTick() + delay; long tick = Limbo.getInstance().getHeartBeat().getCurrentTick() + delay;
tasksById.put(taskId, st); tasksById.put(taskId, st);
List<LimboSchedulerTask> list = registeredTasks.get(tick); List<LimboSchedulerTask> list = registeredTasks.get(tick);
if (list == null) { if (list == null) {
list = new ArrayList<>(); list = new ArrayList<>();
registeredTasks.put(tick, list); registeredTasks.put(tick, list);
} }
list.add(st); list.add(st);
return taskId; return taskId;
} }
public int runTaskTimerAsync(LimboPlugin plugin, LimboTask task, long delay, long period) { public int runTaskTimerAsync(LimboPlugin plugin, LimboTask task, long delay, long period) {
return runTaskTimerAsync(nextId(), plugin, task, delay, period); return runTaskTimerAsync(nextId(), plugin, task, delay, period);
} }
protected CurrentSchedulerTask collectTasks(long currentTick) { protected CurrentSchedulerTask collectTasks(long currentTick) {
List<LimboSchedulerTask> tasks = registeredTasks.remove(currentTick); List<LimboSchedulerTask> tasks = registeredTasks.remove(currentTick);
if (tasks == null) { if (tasks == null) {
return null; return null;
} }
List<LimboSchedulerTask> asyncTasks = new LinkedList<>(); List<LimboSchedulerTask> asyncTasks = new LinkedList<>();
List<LimboSchedulerTask> syncedTasks = new LinkedList<>(); List<LimboSchedulerTask> syncedTasks = new LinkedList<>();
for (LimboSchedulerTask task : tasks) { for (LimboSchedulerTask task : tasks) {
int taskId = task.getTaskId(); int taskId = task.getTaskId();
if (cancelledTasks.contains(taskId)) { if (cancelledTasks.contains(taskId)) {
cancelledTasks.remove(taskId); cancelledTasks.remove(taskId);
continue; continue;
} }
switch (task.getType()) { switch (task.getType()) {
case ASYNC: case ASYNC:
asyncTasks.add(task); asyncTasks.add(task);
break; break;
case SYNC: case SYNC:
syncedTasks.add(task); syncedTasks.add(task);
break; break;
case TIMER_ASYNC: case TIMER_ASYNC:
asyncTasks.add(task); asyncTasks.add(task);
runTaskTimerAsync(task.getTaskId(), task.getPlugin(), task.getTask(), task.getPeriod(), task.getPeriod()); runTaskTimerAsync(task.getTaskId(), task.getPlugin(), task.getTask(), task.getPeriod(), task.getPeriod());
break; break;
case TIMER_SYNC: case TIMER_SYNC:
syncedTasks.add(task); syncedTasks.add(task);
runTaskTimer(task.getTaskId(), task.getPlugin(), task.getTask(), task.getPeriod(), task.getPeriod()); runTaskTimer(task.getTaskId(), task.getPlugin(), task.getTask(), task.getPeriod(), task.getPeriod());
break; break;
} }
} }
return new CurrentSchedulerTask(syncedTasks, asyncTasks); return new CurrentSchedulerTask(syncedTasks, asyncTasks);
} }
public static class CurrentSchedulerTask { public enum LimboSchedulerTaskType {
private List<LimboSchedulerTask> asyncTasks; SYNC,
private List<LimboSchedulerTask> syncedTasks; ASYNC,
TIMER_SYNC,
TIMER_ASYNC
public CurrentSchedulerTask(List<LimboSchedulerTask> syncedTasks, List<LimboSchedulerTask> asyncTasks) { }
this.asyncTasks = asyncTasks;
this.syncedTasks = syncedTasks;
}
public List<LimboSchedulerTask> getAsyncTasks() { public static class CurrentSchedulerTask {
return asyncTasks;
}
public List<LimboSchedulerTask> getSyncedTasks() { private final List<LimboSchedulerTask> asyncTasks;
return syncedTasks; private final List<LimboSchedulerTask> syncedTasks;
}
} public CurrentSchedulerTask(List<LimboSchedulerTask> syncedTasks, List<LimboSchedulerTask> asyncTasks) {
this.asyncTasks = asyncTasks;
this.syncedTasks = syncedTasks;
}
public static class LimboSchedulerTask { public List<LimboSchedulerTask> getAsyncTasks() {
return asyncTasks;
}
private int taskId; public List<LimboSchedulerTask> getSyncedTasks() {
private LimboPlugin plugin; return syncedTasks;
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() { public static class LimboSchedulerTask {
return plugin;
}
public LimboTask getTask() { private final int taskId;
return task; private final LimboPlugin plugin;
} private final LimboTask task;
private final LimboSchedulerTaskType type;
private final long period;
public int getTaskId() { private LimboSchedulerTask(LimboPlugin plugin, LimboTask task, int taskId, LimboSchedulerTaskType type, long period) {
return taskId; this.plugin = plugin;
} this.task = task;
this.taskId = taskId;
this.type = type;
this.period = period;
}
public LimboSchedulerTaskType getType() { public LimboPlugin getPlugin() {
return type; return plugin;
} }
public long getPeriod() { public LimboTask getTask() {
return period; return task;
} }
} public int getTaskId() {
return taskId;
}
public static enum LimboSchedulerTaskType { public LimboSchedulerTaskType getType() {
return type;
}
SYNC, public long getPeriod() {
ASYNC, return period;
TIMER_SYNC, }
TIMER_ASYNC;
} }
} }

View File

@ -1,5 +1,9 @@
package com.loohp.limbo.scheduler; 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.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -8,62 +12,58 @@ import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong; 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 { public class Tick {
private int tickingInterval; private int tickingInterval;
private AtomicLong tick = new AtomicLong(0); private final AtomicLong tick = new AtomicLong(0);
private List<Thread> threads = new ArrayList<>(); private final List<Thread> threads = new ArrayList<>();
private Queue<LimboSchedulerTask> asyncTasksQueue = new ConcurrentLinkedQueue<>(); private final Queue<LimboSchedulerTask> asyncTasksQueue = new ConcurrentLinkedQueue<>();
public Tick(Limbo instance) { public Tick(Limbo instance) {
new Thread(new Runnable() { new Thread(new Runnable() {
@Override @Override
public void run() { public void run() {
tickingInterval = (int) Math.round(1000.0 / Limbo.getInstance().getServerProperties().getDefinedTicksPerSecond()); tickingInterval = (int) Math.round(1000.0 / Limbo.getInstance().getServerProperties().getDefinedTicksPerSecond());
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
Thread thread = new Thread(new Runnable() { Thread thread = new Thread(new Runnable() {
@Override @Override
public void run() { public void run() {
while (instance.isRunning()) { while (instance.isRunning()) {
LimboSchedulerTask task = asyncTasksQueue.poll(); LimboSchedulerTask task = asyncTasksQueue.poll();
if (task == null) { if (task == null) {
try { try {
TimeUnit.NANOSECONDS.sleep(10000); TimeUnit.NANOSECONDS.sleep(10000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
} else { } else {
LimboTask limboTask = task.getTask(); LimboTask limboTask = task.getTask();
try { try {
limboTask.run(); limboTask.run();
} catch (Throwable e) { } catch (Throwable e) {
System.err.println("Task " + task.getTaskId() + " threw an exception: " + e.getLocalizedMessage()); System.err.println("Task " + task.getTaskId() + " threw an exception: " + e.getLocalizedMessage());
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
} }
}); });
thread.start(); thread.start();
threads.add(thread); threads.add(thread);
} }
while (instance.isRunning()) { while (instance.isRunning()) {
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
tick.incrementAndGet(); tick.incrementAndGet();
instance.getPlayers().forEach(each -> { instance.getPlayers().forEach(each -> {
if (each.clientConnection.isReady()) { if (each.clientConnection.isReady()) {
try { try {
each.playerInteractManager.update(); each.playerInteractManager.update();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
/* /*
try { try {
each.getDataWatcher().update(); each.getDataWatcher().update();
@ -71,59 +71,59 @@ public class Tick {
e.printStackTrace(); e.printStackTrace();
} }
*/ */
} }
}); });
instance.getWorlds().forEach(each -> { instance.getWorlds().forEach(each -> {
try { try {
each.update(); each.update();
} catch (IllegalArgumentException | IllegalAccessException e) { } catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace(); e.printStackTrace();
} }
}); });
CurrentSchedulerTask tasks = instance.getScheduler().collectTasks(getCurrentTick()); CurrentSchedulerTask tasks = instance.getScheduler().collectTasks(getCurrentTick());
if (tasks != null) { if (tasks != null) {
asyncTasksQueue.addAll(tasks.getAsyncTasks()); asyncTasksQueue.addAll(tasks.getAsyncTasks());
tasks.getSyncedTasks().forEach(task -> { tasks.getSyncedTasks().forEach(task -> {
LimboTask limboTask = task.getTask(); LimboTask limboTask = task.getTask();
try { try {
limboTask.run(); limboTask.run();
} catch (Throwable e) { } catch (Throwable e) {
System.err.println("Task " + task.getTaskId() + " threw an exception: " + e.getLocalizedMessage()); System.err.println("Task " + task.getTaskId() + " threw an exception: " + e.getLocalizedMessage());
e.printStackTrace(); e.printStackTrace();
} }
}); });
} }
long end = System.currentTimeMillis(); long end = System.currentTimeMillis();
try { try {
TimeUnit.MILLISECONDS.sleep(tickingInterval - (end - start)); TimeUnit.MILLISECONDS.sleep(tickingInterval - (end - start));
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
}).start(); }).start();
} }
public long getCurrentTick() { public long getCurrentTick() {
return tick.get(); return tick.get();
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void waitAndKillThreads(long waitTime) { public void waitAndKillThreads(long waitTime) {
long end = System.currentTimeMillis() + waitTime; long end = System.currentTimeMillis() + waitTime;
for (Thread thread : threads) { for (Thread thread : threads) {
try { try {
thread.join(Math.max(end - System.currentTimeMillis(), 1)); thread.join(Math.max(end - System.currentTimeMillis(), 1));
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
if (thread.isAlive()) { if (thread.isAlive()) {
thread.stop(); thread.stop();
} }
} }
} }
} }

View File

@ -1,104 +1,49 @@
package com.loohp.limbo.server; 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.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.Socket; import java.net.Socket;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.*;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors; 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 class ClientConnection extends Thread {
public static enum ClientState {
LEGACY,
HANDSHAKE,
STATUS,
LOGIN,
PLAY,
DISCONNECTED;
}
private final Socket client_socket; private final Socket client_socket;
private boolean running; private boolean running;
private ClientState state; private ClientState state;
private Player player; private Player player;
private AtomicLong lastKeepAlivePayLoad; private final AtomicLong lastKeepAlivePayLoad;
private DataOutputStream output;
private DataOutputStream output; private DataInputStream input;
private DataInputStream input; private InetAddress inetAddress;
private boolean ready;
private InetAddress inetAddress;
private boolean ready;
public ClientConnection(Socket client_socket) { public ClientConnection(Socket client_socket) {
this.client_socket = client_socket; this.client_socket = client_socket;
@ -108,365 +53,381 @@ public class ClientConnection extends Thread {
this.ready = false; this.ready = false;
} }
public InetAddress getInetAddress() { public InetAddress getInetAddress() {
return inetAddress; return inetAddress;
} }
public long getLastKeepAlivePayLoad() { public long getLastKeepAlivePayLoad() {
return lastKeepAlivePayLoad.get(); return lastKeepAlivePayLoad.get();
} }
public void setLastKeepAlivePayLoad(long payLoad) { public void setLastKeepAlivePayLoad(long payLoad) {
this.lastKeepAlivePayLoad.set(payLoad); this.lastKeepAlivePayLoad.set(payLoad);
} }
public Player getPlayer() { public Player getPlayer() {
return player; return player;
} }
public ClientState getClientState() { public ClientState getClientState() {
return state; return state;
} }
public Socket getSocket() { public Socket getSocket() {
return client_socket; return client_socket;
} }
public boolean isRunning() { public boolean isRunning() {
return running; return running;
} }
public boolean isReady() { public boolean isReady() {
return ready; return ready;
} }
public synchronized void sendPacket(PacketOut packet) throws IOException { public synchronized void sendPacket(PacketOut packet) throws IOException {
byte[] packetByte = packet.serializePacket(); byte[] packetByte = packet.serializePacket();
DataTypeIO.writeVarInt(output, packetByte.length); DataTypeIO.writeVarInt(output, packetByte.length);
output.write(packetByte); output.write(packetByte);
output.flush(); output.flush();
} }
public void disconnect(BaseComponent[] reason) { public void disconnect(BaseComponent[] reason) {
try { try {
PacketPlayOutDisconnect packet = new PacketPlayOutDisconnect(ComponentSerializer.toString(reason)); PacketPlayOutDisconnect packet = new PacketPlayOutDisconnect(ComponentSerializer.toString(reason));
sendPacket(packet); sendPacket(packet);
} catch (IOException e) {} } catch (IOException e) {
try { }
client_socket.close(); try {
} catch (IOException e) {} client_socket.close();
} } catch (IOException e) {
}
}
private void disconnectDuringLogin(BaseComponent[] reason) { private void disconnectDuringLogin(BaseComponent[] reason) {
try { try {
PacketLoginOutDisconnect packet = new PacketLoginOutDisconnect(ComponentSerializer.toString(reason)); PacketLoginOutDisconnect packet = new PacketLoginOutDisconnect(ComponentSerializer.toString(reason));
sendPacket(packet); sendPacket(packet);
} catch (IOException e) {} } catch (IOException e) {
try { }
client_socket.close(); try {
} catch (IOException e) {} client_socket.close();
} } catch (IOException e) {
}
}
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@Override @Override
public void run() { public void run() {
running = true; running = true;
state = ClientState.HANDSHAKE; state = ClientState.HANDSHAKE;
try { try {
client_socket.setKeepAlive(true); client_socket.setKeepAlive(true);
input = new DataInputStream(client_socket.getInputStream()); input = new DataInputStream(client_socket.getInputStream());
output = new DataOutputStream(client_socket.getOutputStream()); output = new DataOutputStream(client_socket.getOutputStream());
int handShakeSize = DataTypeIO.readVarInt(input); int handShakeSize = DataTypeIO.readVarInt(input);
//legacy ping //legacy ping
if (handShakeSize == 0xFE) { if (handShakeSize == 0xFE) {
state = ClientState.LEGACY; state = ClientState.LEGACY;
output.writeByte(255); output.writeByte(255);
String str = inetAddress.getHostName() + ":" + client_socket.getPort(); String str = inetAddress.getHostName() + ":" + client_socket.getPort();
Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Legacy Status has pinged"); Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Legacy Status has pinged");
ServerProperties p = Limbo.getInstance().getServerProperties(); 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))); 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()); String response = Limbo.getInstance().buildLegacyPingResponse(event.getVersion(), event.getMotd(), event.getMaxPlayers(), event.getPlayersOnline());
byte[] bytes = response.getBytes(StandardCharsets.UTF_16BE); byte[] bytes = response.getBytes(StandardCharsets.UTF_16BE);
output.writeShort(response.length()); output.writeShort(response.length());
output.write(bytes); output.write(bytes);
client_socket.close(); client_socket.close();
state = ClientState.DISCONNECTED; state = ClientState.DISCONNECTED;
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
int handShakeId = DataTypeIO.readVarInt(input); int handShakeId = DataTypeIO.readVarInt(input);
PacketHandshakingIn handshake = new PacketHandshakingIn(input); PacketHandshakingIn handshake = new PacketHandshakingIn(input);
boolean isBungeecord = Limbo.getInstance().getServerProperties().isBungeecord(); boolean isBungeecord = Limbo.getInstance().getServerProperties().isBungeecord();
String bungeeForwarding = handshake.getServerAddress(); String bungeeForwarding = handshake.getServerAddress();
UUID bungeeUUID = null; UUID bungeeUUID = null;
SkinResponse bungeeSkin = null; SkinResponse bungeeSkin = null;
try { try {
switch (handshake.getHandshakeType()) { switch (handshake.getHandshakeType()) {
case STATUS: case STATUS:
state = ClientState.STATUS; state = ClientState.STATUS;
while (client_socket.isConnected()) { while (client_socket.isConnected()) {
DataTypeIO.readVarInt(input); DataTypeIO.readVarInt(input);
int packetId = DataTypeIO.readVarInt(input); int packetId = DataTypeIO.readVarInt(input);
Class<? extends Packet> packetType = Packet.getStatusIn().get(packetId); Class<? extends Packet> packetType = Packet.getStatusIn().get(packetId);
if (packetType == null) { if (packetType == null) {
//do nothing //do nothing
} else if (packetType.equals(PacketStatusInRequest.class)) { } else if (packetType.equals(PacketStatusInRequest.class)) {
String str = inetAddress.getHostName() + ":" + client_socket.getPort(); String str = inetAddress.getHostName() + ":" + client_socket.getPort();
if (Limbo.getInstance().getServerProperties().handshakeVerboseEnabled()) { if (Limbo.getInstance().getServerProperties().handshakeVerboseEnabled()) {
Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Handshake Status has pinged"); Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Handshake Status has pinged");
} }
ServerProperties p = Limbo.getInstance().getServerProperties(); 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))); 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())); PacketStatusOutResponse packet = new PacketStatusOutResponse(Limbo.getInstance().buildServerListResponseJson(event.getVersion(), event.getProtocol(), event.getMotd(), event.getMaxPlayers(), event.getPlayersOnline(), event.getFavicon()));
sendPacket(packet); sendPacket(packet);
} else if (packetType.equals(PacketStatusInPing.class)) { } else if (packetType.equals(PacketStatusInPing.class)) {
PacketStatusInPing ping = new PacketStatusInPing(input); PacketStatusInPing ping = new PacketStatusInPing(input);
PacketStatusOutPong packet = new PacketStatusOutPong(ping.getPayload()); PacketStatusOutPong packet = new PacketStatusOutPong(ping.getPayload());
sendPacket(packet); sendPacket(packet);
break; break;
} }
} }
break; break;
case LOGIN: case LOGIN:
state = ClientState.LOGIN; state = ClientState.LOGIN;
if (isBungeecord) { if (isBungeecord) {
try { try {
String[] data = bungeeForwarding.split("\\x00"); String[] data = bungeeForwarding.split("\\x00");
//String host = data[0]; //String host = data[0];
String ip = data[1]; 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")); 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); inetAddress = InetAddress.getByName(ip);
if (data.length > 3) { if (data.length > 3) {
String skinJson = data[3]; String skinJson = data[3];
String skin = skinJson.split("\"value\":\"")[1].split("\"")[0]; String skin = skinJson.split("\"value\":\"")[1].split("\"")[0];
String signature = skinJson.split("\"signature\":\"")[1].split("\"")[0]; String signature = skinJson.split("\"signature\":\"")[1].split("\"")[0];
bungeeSkin = new SkinResponse(skin, signature); bungeeSkin = new SkinResponse(skin, signature);
} }
} catch (Exception e) { } 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!"); 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!")}); disconnectDuringLogin(new BaseComponent[]{new TextComponent(ChatColor.RED + "Please connect from the proxy!")});
} }
} }
while (client_socket.isConnected()) { while (client_socket.isConnected()) {
int size = DataTypeIO.readVarInt(input); int size = DataTypeIO.readVarInt(input);
int packetId = DataTypeIO.readVarInt(input); int packetId = DataTypeIO.readVarInt(input);
Class<? extends Packet> packetType = Packet.getLoginIn().get(packetId); Class<? extends Packet> packetType = Packet.getLoginIn().get(packetId);
if (packetType == null) { if (packetType == null) {
input.skipBytes(size - DataTypeIO.getVarIntLength(packetId)); input.skipBytes(size - DataTypeIO.getVarIntLength(packetId));
} else if (packetType.equals(PacketLoginInLoginStart.class)) { } else if (packetType.equals(PacketLoginInLoginStart.class)) {
PacketLoginInLoginStart start = new PacketLoginInLoginStart(input); PacketLoginInLoginStart start = new PacketLoginInLoginStart(input);
String username = start.getUsername(); String username = start.getUsername();
UUID uuid = isBungeecord ? bungeeUUID : UUID.nameUUIDFromBytes(("OfflinePlayer:" + username).getBytes(StandardCharsets.UTF_8)); UUID uuid = isBungeecord ? bungeeUUID : UUID.nameUUIDFromBytes(("OfflinePlayer:" + username).getBytes(StandardCharsets.UTF_8));
PacketLoginOutLoginSuccess success = new PacketLoginOutLoginSuccess(uuid, username); PacketLoginOutLoginSuccess success = new PacketLoginOutLoginSuccess(uuid, username);
sendPacket(success); sendPacket(success);
state = ClientState.PLAY; state = ClientState.PLAY;
player = new Player(this, username, uuid, Limbo.getInstance().getNextEntityId(), Limbo.getInstance().getServerProperties().getWorldSpawn(), new PlayerInteractManager()); 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)); player.setSkinLayers((byte) (0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40));
Limbo.getInstance().addPlayer(player); Limbo.getInstance().addPlayer(player);
break; break;
} else { } else {
input.skipBytes(size - DataTypeIO.getVarIntLength(packetId)); input.skipBytes(size - DataTypeIO.getVarIntLength(packetId));
} }
} }
PlayerLoginEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerLoginEvent(this, false)); PlayerLoginEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerLoginEvent(this, false));
if (event.isCancelled()) { if (event.isCancelled()) {
disconnectDuringLogin(event.getCancelReason()); disconnectDuringLogin(event.getCancelReason());
} }
break; break;
} }
} catch (Exception e) { } catch (Exception e) {
client_socket.close(); client_socket.close();
state = ClientState.DISCONNECTED; state = ClientState.DISCONNECTED;
} }
if (state == ClientState.PLAY) { if (state == ClientState.PLAY) {
TimeUnit.MILLISECONDS.sleep(500); TimeUnit.MILLISECONDS.sleep(500);
ServerProperties properties = Limbo.getInstance().getServerProperties(); ServerProperties properties = Limbo.getInstance().getServerProperties();
Location worldSpawn = properties.getWorldSpawn(); Location worldSpawn = properties.getWorldSpawn();
PlayerJoinEvent joinEvent = Limbo.getInstance().getEventsManager().callEvent(new PlayerJoinEvent(player, worldSpawn)); PlayerJoinEvent joinEvent = Limbo.getInstance().getEventsManager().callEvent(new PlayerJoinEvent(player, worldSpawn));
worldSpawn = joinEvent.getSpawnLocation(); worldSpawn = joinEvent.getSpawnLocation();
World world = worldSpawn.getWorld(); 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); 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); sendPacket(join);
Limbo.getInstance().getUnsafe().setPlayerGameModeSilently(player, properties.getDefaultGamemode()); Limbo.getInstance().getUnsafe().setPlayerGameModeSilently(player, properties.getDefaultGamemode());
player.playerInteractManager.update(); player.playerInteractManager.update();
SkinResponse skinresponce = isBungeecord && bungeeSkin != null ? bungeeSkin : MojangAPIUtils.getSkinFromMojangServer(player.getName()); SkinResponse skinresponce = isBungeecord && bungeeSkin != null ? bungeeSkin : MojangAPIUtils.getSkinFromMojangServer(player.getName());
PlayerSkinProperty skin = skinresponce != null ? new PlayerSkinProperty(skinresponce.getSkin(), skinresponce.getSignature()) : null; 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())); 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); sendPacket(info);
Set<PlayerAbilityFlags> flags = new HashSet<>(); Set<PlayerAbilityFlags> flags = new HashSet<>();
if (properties.isAllowFlight()) { if (properties.isAllowFlight()) {
flags.add(PlayerAbilityFlags.FLY); flags.add(PlayerAbilityFlags.FLY);
} }
if (player.getGamemode().equals(GameMode.CREATIVE)) { if (player.getGamemode().equals(GameMode.CREATIVE)) {
flags.add(PlayerAbilityFlags.CREATIVE); flags.add(PlayerAbilityFlags.CREATIVE);
} }
PacketPlayOutPlayerAbilities abilities = new PacketPlayOutPlayerAbilities(0.05F, 0.1F, flags.toArray(new PlayerAbilityFlags[flags.size()])); PacketPlayOutPlayerAbilities abilities = new PacketPlayOutPlayerAbilities(0.05F, 0.1F, flags.toArray(new PlayerAbilityFlags[flags.size()]));
sendPacket(abilities); sendPacket(abilities);
String str = inetAddress.getHostName() + ":" + client_socket.getPort() + "|" + player.getName(); String str = inetAddress.getHostName() + ":" + client_socket.getPort() + "|" + player.getName();
Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Player had connected to the Limbo server!"); Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Player had connected to the Limbo server!");
PacketPlayOutDeclareCommands declare = DeclareCommands.getDeclareCommandsPacket(player); PacketPlayOutDeclareCommands declare = DeclareCommands.getDeclareCommandsPacket(player);
if (declare != null) { if (declare != null) {
sendPacket(declare); sendPacket(declare);
} }
PacketPlayOutSpawnPosition spawnPos = new PacketPlayOutSpawnPosition(BlockPosition.from(worldSpawn)); PacketPlayOutSpawnPosition spawnPos = new PacketPlayOutSpawnPosition(BlockPosition.from(worldSpawn));
sendPacket(spawnPos); sendPacket(spawnPos);
PacketPlayOutPositionAndLook positionLook = new PacketPlayOutPositionAndLook(worldSpawn.getX(), worldSpawn.getY(), worldSpawn.getZ(), worldSpawn.getYaw(), worldSpawn.getPitch(), 1); 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())); Limbo.getInstance().getUnsafe().setPlayerLocationSilently(player, new Location(world, worldSpawn.getX(), worldSpawn.getY(), worldSpawn.getZ(), worldSpawn.getYaw(), worldSpawn.getPitch()));
sendPacket(positionLook); sendPacket(positionLook);
player.getDataWatcher().update(); player.getDataWatcher().update();
PacketPlayOutEntityMetadata show = new PacketPlayOutEntityMetadata(player, false, Player.class.getDeclaredField("skinLayers")); PacketPlayOutEntityMetadata show = new PacketPlayOutEntityMetadata(player, false, Player.class.getDeclaredField("skinLayers"));
sendPacket(show); sendPacket(show);
ready = true; ready = true;
while (client_socket.isConnected()) { while (client_socket.isConnected()) {
try { try {
int size = DataTypeIO.readVarInt(input); int size = DataTypeIO.readVarInt(input);
int packetId = DataTypeIO.readVarInt(input); int packetId = DataTypeIO.readVarInt(input);
Class<? extends Packet> packetType = Packet.getPlayIn().get(packetId); Class<? extends Packet> packetType = Packet.getPlayIn().get(packetId);
//Limbo.getInstance().getConsole().sendMessage(packetId + " -> " + packetType); //Limbo.getInstance().getConsole().sendMessage(packetId + " -> " + packetType);
CheckedConsumer<PlayerMoveEvent, IOException> processMoveEvent = event -> { CheckedConsumer<PlayerMoveEvent, IOException> processMoveEvent = event -> {
Location originalTo = event.getTo().clone(); Location originalTo = event.getTo().clone();
if (event.isCancelled()) { if (event.isCancelled()) {
Location returnTo = event.getFrom(); Location returnTo = event.getFrom();
PacketPlayOutPositionAndLook cancel = new PacketPlayOutPositionAndLook(returnTo.getX(), returnTo.getY(), returnTo.getZ(), returnTo.getYaw(), returnTo.getPitch(), 1); PacketPlayOutPositionAndLook cancel = new PacketPlayOutPositionAndLook(returnTo.getX(), returnTo.getY(), returnTo.getZ(), returnTo.getYaw(), returnTo.getPitch(), 1);
sendPacket(cancel); sendPacket(cancel);
} else { } else {
Location to = event.getTo(); Location to = event.getTo();
Limbo.getInstance().getUnsafe().setPlayerLocationSilently(player, to); Limbo.getInstance().getUnsafe().setPlayerLocationSilently(player, to);
// If an event handler used setTo, let's make sure we tell the player about it. // If an event handler used setTo, let's make sure we tell the player about it.
if (!originalTo.equals(to)) { if (!originalTo.equals(to)) {
PacketPlayOutPositionAndLook pos = new PacketPlayOutPositionAndLook(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch(), 1); PacketPlayOutPositionAndLook pos = new PacketPlayOutPositionAndLook(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch(), 1);
sendPacket(pos); sendPacket(pos);
} }
PacketPlayOutUpdateViewPosition response = new PacketPlayOutUpdateViewPosition((int) player.getLocation().getX() >> 4, (int) player.getLocation().getZ() >> 4); PacketPlayOutUpdateViewPosition response = new PacketPlayOutUpdateViewPosition((int) player.getLocation().getX() >> 4, (int) player.getLocation().getZ() >> 4);
sendPacket(response); sendPacket(response);
} }
}; };
if (packetType == null) { if (packetType == null) {
input.skipBytes(size - DataTypeIO.getVarIntLength(packetId)); input.skipBytes(size - DataTypeIO.getVarIntLength(packetId));
} else if (packetType.equals(PacketPlayInPositionAndLook.class)) { } else if (packetType.equals(PacketPlayInPositionAndLook.class)) {
PacketPlayInPositionAndLook pos = new PacketPlayInPositionAndLook(input); PacketPlayInPositionAndLook pos = new PacketPlayInPositionAndLook(input);
Location from = player.getLocation(); Location from = player.getLocation();
Location to = new Location(player.getWorld(), pos.getX(), pos.getY(), pos.getZ(), pos.getYaw(), pos.getPitch()); 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)); PlayerMoveEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerMoveEvent(player, from, to));
processMoveEvent.consume(event); processMoveEvent.consume(event);
} else if (packetType.equals(PacketPlayInPosition.class)) { } else if (packetType.equals(PacketPlayInPosition.class)) {
PacketPlayInPosition pos = new PacketPlayInPosition(input); PacketPlayInPosition pos = new PacketPlayInPosition(input);
Location from = player.getLocation(); Location from = player.getLocation();
Location to = new Location(player.getWorld(), pos.getX(), pos.getY(), pos.getZ(), player.getLocation().getYaw(), player.getLocation().getPitch()); 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)); PlayerMoveEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerMoveEvent(player, from, to));
processMoveEvent.consume(event); processMoveEvent.consume(event);
} else if (packetType.equals(PacketPlayInRotation.class)) { } else if (packetType.equals(PacketPlayInRotation.class)) {
PacketPlayInRotation pos = new PacketPlayInRotation(input); PacketPlayInRotation pos = new PacketPlayInRotation(input);
Location from = player.getLocation(); Location from = player.getLocation();
Location to = new Location(player.getWorld(), player.getLocation().getX(), player.getLocation().getY(), player.getLocation().getZ(), pos.getYaw(), pos.getPitch()); 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)); PlayerMoveEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerMoveEvent(player, from, to));
processMoveEvent.consume(event); processMoveEvent.consume(event);
} else if (packetType.equals(PacketPlayInKeepAlive.class)) { } else if (packetType.equals(PacketPlayInKeepAlive.class)) {
PacketPlayInKeepAlive alive = new PacketPlayInKeepAlive(input); PacketPlayInKeepAlive alive = new PacketPlayInKeepAlive(input);
if (alive.getPayload() != getLastKeepAlivePayLoad()) { if (alive.getPayload() != getLastKeepAlivePayLoad()) {
Limbo.getInstance().getConsole().sendMessage("Incorrect Payload recieved in KeepAlive packet for player " + player.getName()); Limbo.getInstance().getConsole().sendMessage("Incorrect Payload recieved in KeepAlive packet for player " + player.getName());
break; break;
} }
} else if (packetType.equals(PacketPlayInTabComplete.class)) { } else if (packetType.equals(PacketPlayInTabComplete.class)) {
PacketPlayInTabComplete request = new PacketPlayInTabComplete(input); PacketPlayInTabComplete request = new PacketPlayInTabComplete(input);
String[] command = CustomStringUtils.splitStringToArgs(request.getText().substring(1)); String[] command = CustomStringUtils.splitStringToArgs(request.getText().substring(1));
List<TabCompleteMatches> matches = new ArrayList<TabCompleteMatches>(); List<TabCompleteMatches> matches = new ArrayList<TabCompleteMatches>();
matches.addAll(Limbo.getInstance().getPluginManager().getTabOptions(player, command).stream().map(each -> new TabCompleteMatches(each)).collect(Collectors.toList())); 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 start = CustomStringUtils.getIndexOfArg(request.getText(), command.length - 1) + 1;
int length = command[command.length - 1].length(); int length = command[command.length - 1].length();
PacketPlayOutTabComplete response = new PacketPlayOutTabComplete(request.getId(), start, length, matches.toArray(new TabCompleteMatches[matches.size()])); PacketPlayOutTabComplete response = new PacketPlayOutTabComplete(request.getId(), start, length, matches.toArray(new TabCompleteMatches[matches.size()]));
sendPacket(response); sendPacket(response);
} else if (packetType.equals(PacketPlayInChat.class)) { } else if (packetType.equals(PacketPlayInChat.class)) {
PacketPlayInChat chat = new PacketPlayInChat(input); PacketPlayInChat chat = new PacketPlayInChat(input);
if (chat.getMessage().startsWith("/")) { if (chat.getMessage().startsWith("/")) {
Limbo.getInstance().dispatchCommand(player, chat.getMessage()); Limbo.getInstance().dispatchCommand(player, chat.getMessage());
} else { } else {
player.chat(chat.getMessage()); player.chat(chat.getMessage());
} }
} else if (packetType.equals(PacketPlayInHeldItemChange.class)) { } else if (packetType.equals(PacketPlayInHeldItemChange.class)) {
PacketPlayInHeldItemChange change = new PacketPlayInHeldItemChange(input); PacketPlayInHeldItemChange change = new PacketPlayInHeldItemChange(input);
PlayerSelectedSlotChangeEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerSelectedSlotChangeEvent(player, (byte) change.getSlot())); PlayerSelectedSlotChangeEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerSelectedSlotChangeEvent(player, (byte) change.getSlot()));
if (event.isCancelled()) { if (event.isCancelled()) {
PacketPlayOutHeldItemChange cancelPacket = new PacketPlayOutHeldItemChange(player.getSelectedSlot()); PacketPlayOutHeldItemChange cancelPacket = new PacketPlayOutHeldItemChange(player.getSelectedSlot());
sendPacket(cancelPacket); sendPacket(cancelPacket);
} else if (change.getSlot() != event.getSlot()) { } else if (change.getSlot() != event.getSlot()) {
PacketPlayOutHeldItemChange changePacket = new PacketPlayOutHeldItemChange(event.getSlot()); PacketPlayOutHeldItemChange changePacket = new PacketPlayOutHeldItemChange(event.getSlot());
sendPacket(changePacket); sendPacket(changePacket);
Limbo.getInstance().getUnsafe().setSelectedSlotSilently(player, event.getSlot()); Limbo.getInstance().getUnsafe().setSelectedSlotSilently(player, event.getSlot());
} else { } else {
Limbo.getInstance().getUnsafe().setSelectedSlotSilently(player, event.getSlot()); Limbo.getInstance().getUnsafe().setSelectedSlotSilently(player, event.getSlot());
} }
} else { } else {
input.skipBytes(size - DataTypeIO.getVarIntLength(packetId)); input.skipBytes(size - DataTypeIO.getVarIntLength(packetId));
} }
} catch (Exception e) { } catch (Exception e) {
break; break;
} }
} }
Limbo.getInstance().getEventsManager().callEvent(new PlayerQuitEvent(player)); Limbo.getInstance().getEventsManager().callEvent(new PlayerQuitEvent(player));
str = inetAddress.getHostName() + ":" + client_socket.getPort() + "|" + player.getName(); str = inetAddress.getHostName() + ":" + client_socket.getPort() + "|" + player.getName();
Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Player had disconnected!"); Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Player had disconnected!");
} }
} catch (Exception e) {e.printStackTrace();} } catch (Exception e) {
e.printStackTrace();
}
try { try {
client_socket.close(); client_socket.close();
} catch (IOException e) {} } catch (IOException e) {
state = ClientState.DISCONNECTED; }
state = ClientState.DISCONNECTED;
if (player != null) { if (player != null) {
Limbo.getInstance().removePlayer(player); Limbo.getInstance().removePlayer(player);
} }
Limbo.getInstance().getServerConnection().getClients().remove(this); Limbo.getInstance().getServerConnection().getClients().remove(this);
running = false; running = false;
} }
@FunctionalInterface public enum ClientState {
public interface CheckedConsumer<T, TException extends Throwable> { LEGACY,
void consume(T t) throws TException; HANDSHAKE,
} STATUS,
LOGIN,
PLAY,
DISCONNECTED
}
@FunctionalInterface
public interface CheckedConsumer<T, TException extends Throwable> {
void consume(T t) throws TException;
}
} }

View File

@ -1,40 +1,41 @@
package com.loohp.limbo.server; 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.Limbo;
import com.loohp.limbo.server.ClientConnection.ClientState; import com.loohp.limbo.server.ClientConnection.ClientState;
import com.loohp.limbo.server.packets.PacketPlayOutKeepAlive; 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 { public class KeepAliveSender extends Thread {
private Random random; private final Random random;
public KeepAliveSender() { public KeepAliveSender() {
random = new Random(); random = new Random();
start(); start();
} }
@Override @Override
public void run() { public void run() {
while (true) { while (true) {
try { try {
for (ClientConnection client : Limbo.getInstance().getServerConnection().getClients()) { for (ClientConnection client : Limbo.getInstance().getServerConnection().getClients()) {
if (client.getClientState() != null && client.getClientState().equals(ClientState.PLAY)) { if (client.getClientState() != null && client.getClientState().equals(ClientState.PLAY)) {
try { try {
PacketPlayOutKeepAlive packet = new PacketPlayOutKeepAlive(random.nextLong()); PacketPlayOutKeepAlive packet = new PacketPlayOutKeepAlive(random.nextLong());
client.setLastKeepAlivePayLoad(packet.getPayload()); client.setLastKeepAlivePayLoad(packet.getPayload());
client.sendPacket(packet); client.sendPacket(packet);
} catch (IOException ignore) {} } catch (IOException ignore) {
} }
} }
TimeUnit.SECONDS.sleep(5); }
} catch (InterruptedException e) { TimeUnit.SECONDS.sleep(5);
e.printStackTrace(); } catch (InterruptedException e) {
} e.printStackTrace();
} }
} }
}
} }

View File

@ -1,5 +1,7 @@
package com.loohp.limbo.server; package com.loohp.limbo.server;
import com.loohp.limbo.Limbo;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.ServerSocket; import java.net.ServerSocket;
@ -7,52 +9,50 @@ import java.net.Socket;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.loohp.limbo.Limbo;
public class ServerConnection extends Thread { public class ServerConnection extends Thread {
private ServerSocket serverSocket; private ServerSocket serverSocket;
private List<ClientConnection> clients; private final List<ClientConnection> clients;
private String ip; private final String ip;
private int port; private final int port;
private KeepAliveSender keepAliveSender; private final KeepAliveSender keepAliveSender;
public ServerConnection(String ip, int port) { public ServerConnection(String ip, int port) {
clients = new ArrayList<ClientConnection>(); clients = new ArrayList<ClientConnection>();
this.ip = ip; this.ip = ip;
this.port = port; this.port = port;
start(); start();
keepAliveSender = new KeepAliveSender(); keepAliveSender = new KeepAliveSender();
} }
@Override @Override
public void run() { public void run() {
try { try {
serverSocket = new ServerSocket(port, 50, InetAddress.getByName(ip)); serverSocket = new ServerSocket(port, 50, InetAddress.getByName(ip));
Limbo.getInstance().getConsole().sendMessage("Limbo server listening on /" + serverSocket.getInetAddress().getHostName() + ":" + serverSocket.getLocalPort()); Limbo.getInstance().getConsole().sendMessage("Limbo server listening on /" + serverSocket.getInetAddress().getHostName() + ":" + serverSocket.getLocalPort());
while (true) { while (true) {
Socket connection = serverSocket.accept(); Socket connection = serverSocket.accept();
//String str = connection.getInetAddress().getHostName() + ":" + connection.getPort(); //String str = connection.getInetAddress().getHostName() + ":" + connection.getPort();
//Limbo.getInstance().getConsole().sendMessage("[/127.0.0.1:57310] <-> InitialHandler has pinged); //Limbo.getInstance().getConsole().sendMessage("[/127.0.0.1:57310] <-> InitialHandler has pinged);
ClientConnection sc = new ClientConnection(connection); ClientConnection sc = new ClientConnection(connection);
clients.add(sc); clients.add(sc);
sc.start(); sc.start();
} }
} catch(IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public KeepAliveSender getKeepAliveSender() { public KeepAliveSender getKeepAliveSender() {
return keepAliveSender; return keepAliveSender;
} }
public ServerSocket getServerSocket() { public ServerSocket getServerSocket() {
return serverSocket; return serverSocket;
} }
public List<ClientConnection> getClients() { public List<ClientConnection> getClients() {
return clients; return clients;
} }
} }

View File

@ -4,71 +4,71 @@ import java.util.Map;
public class Packet { public class Packet {
private static Map<Integer, Class<? extends PacketIn>> HandshakeIn; private static Map<Integer, Class<? extends PacketIn>> HandshakeIn;
private static Map<Integer, Class<? extends PacketIn>> StatusIn; private static Map<Integer, Class<? extends PacketIn>> StatusIn;
private static Map<Class<? extends PacketOut>, Integer> StatusOut; private static Map<Class<? extends PacketOut>, Integer> StatusOut;
private static Map<Integer, Class<? extends PacketIn>> LoginIn; private static Map<Integer, Class<? extends PacketIn>> LoginIn;
private static Map<Class<? extends PacketOut>, Integer> LoginOut; private static Map<Class<? extends PacketOut>, Integer> LoginOut;
private static Map<Integer, Class<? extends PacketIn>> PlayIn; private static Map<Integer, Class<? extends PacketIn>> PlayIn;
private static Map<Class<? extends PacketOut>, Integer> PlayOut; private static Map<Class<? extends PacketOut>, Integer> PlayOut;
public static Map<Integer, Class<? extends PacketIn>> getHandshakeIn() { public static Map<Integer, Class<? extends PacketIn>> getHandshakeIn() {
return HandshakeIn; return HandshakeIn;
} }
public static void setHandshakeIn(Map<Integer, Class<? extends PacketIn>> handshakeIn) { public static void setHandshakeIn(Map<Integer, Class<? extends PacketIn>> handshakeIn) {
HandshakeIn = handshakeIn; HandshakeIn = handshakeIn;
} }
public static Map<Integer, Class<? extends PacketIn>> getStatusIn() { public static Map<Integer, Class<? extends PacketIn>> getStatusIn() {
return StatusIn; return StatusIn;
} }
public static void setStatusIn(Map<Integer, Class<? extends PacketIn>> statusIn) { public static void setStatusIn(Map<Integer, Class<? extends PacketIn>> statusIn) {
StatusIn = statusIn; StatusIn = statusIn;
} }
public static Map<Class<? extends PacketOut>, Integer> getStatusOut() { public static Map<Class<? extends PacketOut>, Integer> getStatusOut() {
return StatusOut; return StatusOut;
} }
public static void setStatusOut(Map<Class<? extends PacketOut>, Integer> statusOut) { public static void setStatusOut(Map<Class<? extends PacketOut>, Integer> statusOut) {
StatusOut = statusOut; StatusOut = statusOut;
} }
public static Map<Integer, Class<? extends PacketIn>> getLoginIn() { public static Map<Integer, Class<? extends PacketIn>> getLoginIn() {
return LoginIn; return LoginIn;
} }
public static void setLoginIn(Map<Integer, Class<? extends PacketIn>> loginIn) { public static void setLoginIn(Map<Integer, Class<? extends PacketIn>> loginIn) {
LoginIn = loginIn; LoginIn = loginIn;
} }
public static Map<Class<? extends PacketOut>, Integer> getLoginOut() { public static Map<Class<? extends PacketOut>, Integer> getLoginOut() {
return LoginOut; return LoginOut;
} }
public static void setLoginOut(Map<Class<? extends PacketOut>, Integer> loginOut) { public static void setLoginOut(Map<Class<? extends PacketOut>, Integer> loginOut) {
LoginOut = loginOut; LoginOut = loginOut;
} }
public static Map<Integer, Class<? extends PacketIn>> getPlayIn() { public static Map<Integer, Class<? extends PacketIn>> getPlayIn() {
return PlayIn; return PlayIn;
} }
public static void setPlayIn(Map<Integer, Class<? extends PacketIn>> playIn) { public static void setPlayIn(Map<Integer, Class<? extends PacketIn>> playIn) {
PlayIn = playIn; PlayIn = playIn;
} }
public static Map<Class<? extends PacketOut>, Integer> getPlayOut() { public static Map<Class<? extends PacketOut>, Integer> getPlayOut() {
return PlayOut; return PlayOut;
} }
public static void setPlayOut(Map<Class<? extends PacketOut>, Integer> playOut) { public static void setPlayOut(Map<Class<? extends PacketOut>, Integer> playOut) {
PlayOut = playOut; PlayOut = playOut;
} }
} }

View File

@ -1,69 +1,68 @@
package com.loohp.limbo.server.packets; package com.loohp.limbo.server.packets;
import com.loohp.limbo.utils.DataTypeIO;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import com.loohp.limbo.utils.DataTypeIO;
public class PacketHandshakingIn extends PacketIn { public class PacketHandshakingIn extends PacketIn {
public static enum HandshakeType { private final int protocolVersion;
STATUS(1),
LOGIN(2);
int networkId; //==============================
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;
}
HandshakeType(int networkId) { public PacketHandshakingIn(DataInputStream in) throws IOException {
this.networkId = networkId; this(DataTypeIO.readVarInt(in), DataTypeIO.readString(in, StandardCharsets.UTF_8), in.readShort() & 0xFFFF, HandshakeType.fromNetworkId(DataTypeIO.readVarInt(in)));
} }
public int getNetworkId() { public int getProtocolVersion() {
return networkId; return protocolVersion;
} }
public static HandshakeType fromNetworkId(int networkId) { public String getServerAddress() {
for (HandshakeType type : HandshakeType.values()) { return serverAddress;
if (type.getNetworkId() == networkId) { }
return type;
}
}
return null;
}
}
//============================== public int getServerPort() {
return serverPort;
}
private int protocolVersion; public HandshakeType getHandshakeType() {
private String serverAddress; return handshakeType;
private int serverPort; }
private HandshakeType handshakeType;
public PacketHandshakingIn(int protocolVersion, String serverAddress, int serverPort, HandshakeType handshakeType) { public enum HandshakeType {
this.protocolVersion = protocolVersion; STATUS(1),
this.serverAddress = serverAddress; LOGIN(2);
this.serverPort = serverPort;
this.handshakeType = handshakeType;
}
public PacketHandshakingIn(DataInputStream in) throws IOException { int networkId;
this(DataTypeIO.readVarInt(in), DataTypeIO.readString(in, StandardCharsets.UTF_8), in.readShort() & 0xFFFF, HandshakeType.fromNetworkId(DataTypeIO.readVarInt(in)));
}
public int getProtocolVersion() { HandshakeType(int networkId) {
return protocolVersion; this.networkId = networkId;
} }
public String getServerAddress() { public static HandshakeType fromNetworkId(int networkId) {
return serverAddress; for (HandshakeType type : HandshakeType.values()) {
} if (type.getNetworkId() == networkId) {
return type;
}
}
return null;
}
public int getServerPort() { public int getNetworkId() {
return serverPort; return networkId;
} }
}
public HandshakeType getHandshakeType() {
return handshakeType;
}
} }

View File

@ -1,25 +1,25 @@
package com.loohp.limbo.server.packets; package com.loohp.limbo.server.packets;
import com.loohp.limbo.utils.DataTypeIO;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import com.loohp.limbo.utils.DataTypeIO;
public class PacketLoginInLoginStart extends PacketIn { public class PacketLoginInLoginStart extends PacketIn {
private String username; private final String username;
public PacketLoginInLoginStart(String username) { public PacketLoginInLoginStart(String username) {
this.username = username; this.username = username;
} }
public PacketLoginInLoginStart(DataInputStream in) throws IOException { public PacketLoginInLoginStart(DataInputStream in) throws IOException {
this(DataTypeIO.readString(in, StandardCharsets.UTF_8)); this(DataTypeIO.readString(in, StandardCharsets.UTF_8));
} }
public String getUsername() { public String getUsername() {
return username; return username;
} }
} }

View File

@ -1,43 +1,43 @@
package com.loohp.limbo.server.packets; 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.DataInputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import com.loohp.limbo.utils.DataTypeIO;
import com.loohp.limbo.utils.NamespacedKey;
public class PacketLoginInPluginMessaging extends PacketIn { public class PacketLoginInPluginMessaging extends PacketIn {
private int messageId; private final int messageId;
private NamespacedKey channel; private final NamespacedKey channel;
private byte[] data; private final byte[] data;
public PacketLoginInPluginMessaging(int messageId, NamespacedKey channel, byte[] data) { public PacketLoginInPluginMessaging(int messageId, NamespacedKey channel, byte[] data) {
this.messageId = messageId; this.messageId = messageId;
this.channel = channel; this.channel = channel;
this.data = data; this.data = data;
} }
public PacketLoginInPluginMessaging(DataInputStream in, int packetLength, int packetId) throws IOException { public PacketLoginInPluginMessaging(DataInputStream in, int packetLength, int packetId) throws IOException {
messageId = DataTypeIO.readVarInt(in); messageId = DataTypeIO.readVarInt(in);
String rawChannel = DataTypeIO.readString(in, StandardCharsets.UTF_8); String rawChannel = DataTypeIO.readString(in, StandardCharsets.UTF_8);
channel = new NamespacedKey(rawChannel); channel = new NamespacedKey(rawChannel);
int dataLength = packetLength - DataTypeIO.getVarIntLength(packetId) - DataTypeIO.getVarIntLength(messageId) - DataTypeIO.getStringLength(rawChannel, StandardCharsets.UTF_8); int dataLength = packetLength - DataTypeIO.getVarIntLength(packetId) - DataTypeIO.getVarIntLength(messageId) - DataTypeIO.getStringLength(rawChannel, StandardCharsets.UTF_8);
data = new byte[dataLength]; data = new byte[dataLength];
in.read(data); in.read(data);
} }
public int getMessageId() { public int getMessageId() {
return messageId; return messageId;
} }
public NamespacedKey getChannel() { public NamespacedKey getChannel() {
return channel; return channel;
} }
public byte[] getData() { public byte[] getData() {
return data; return data;
} }
} }

View File

@ -1,33 +1,33 @@
package com.loohp.limbo.server.packets; package com.loohp.limbo.server.packets;
import com.loohp.limbo.utils.DataTypeIO;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import com.loohp.limbo.utils.DataTypeIO;
public class PacketLoginOutDisconnect extends PacketOut { public class PacketLoginOutDisconnect extends PacketOut {
private String jsonReason; private final String jsonReason;
public PacketLoginOutDisconnect(String jsonReason) { public PacketLoginOutDisconnect(String jsonReason) {
this.jsonReason = jsonReason; this.jsonReason = jsonReason;
} }
public String getJsonReason() { public String getJsonReason() {
return jsonReason; return jsonReason;
} }
@Override @Override
public byte[] serializePacket() throws IOException { public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer); DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getLoginOut().get(getClass())); output.writeByte(Packet.getLoginOut().get(getClass()));
DataTypeIO.writeString(output, jsonReason, StandardCharsets.UTF_8); DataTypeIO.writeString(output, jsonReason, StandardCharsets.UTF_8);
return buffer.toByteArray(); return buffer.toByteArray();
} }
} }

View File

@ -1,41 +1,41 @@
package com.loohp.limbo.server.packets; package com.loohp.limbo.server.packets;
import com.loohp.limbo.utils.DataTypeIO;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.UUID; import java.util.UUID;
import com.loohp.limbo.utils.DataTypeIO;
public class PacketLoginOutLoginSuccess extends PacketOut { public class PacketLoginOutLoginSuccess extends PacketOut {
private UUID uuid; private final UUID uuid;
private String username; private final String username;
public PacketLoginOutLoginSuccess(UUID uuid, String username) { public PacketLoginOutLoginSuccess(UUID uuid, String username) {
this.uuid = uuid; this.uuid = uuid;
this.username = username; this.username = username;
} }
public UUID getUuid() { public UUID getUuid() {
return uuid; return uuid;
} }
public String getUsername() { public String getUsername() {
return username; return username;
} }
@Override @Override
public byte[] serializePacket() throws IOException { public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer); DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getLoginOut().get(getClass())); output.writeByte(Packet.getLoginOut().get(getClass()));
DataTypeIO.writeUUID(output, uuid); DataTypeIO.writeUUID(output, uuid);
DataTypeIO.writeString(output, username, StandardCharsets.UTF_8); DataTypeIO.writeString(output, username, StandardCharsets.UTF_8);
return buffer.toByteArray(); return buffer.toByteArray();
} }
} }

View File

@ -1,48 +1,48 @@
package com.loohp.limbo.server.packets; 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.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import com.loohp.limbo.utils.DataTypeIO;
import com.loohp.limbo.utils.NamespacedKey;
public class PacketLoginOutPluginMessaging extends PacketOut { public class PacketLoginOutPluginMessaging extends PacketOut {
private int messageId; private final int messageId;
private NamespacedKey channel; private final NamespacedKey channel;
private byte[] data; private final byte[] data;
public PacketLoginOutPluginMessaging(int messageId, NamespacedKey channel, byte[] data) { public PacketLoginOutPluginMessaging(int messageId, NamespacedKey channel, byte[] data) {
this.messageId = messageId; this.messageId = messageId;
this.channel = channel; this.channel = channel;
this.data = data; this.data = data;
} }
public int getMessageId() { public int getMessageId() {
return messageId; return messageId;
} }
public NamespacedKey getChannel() { public NamespacedKey getChannel() {
return channel; return channel;
} }
public byte[] getData() { public byte[] getData() {
return data; return data;
} }
@Override @Override
public byte[] serializePacket() throws IOException { public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer); DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getLoginOut().get(getClass())); output.writeByte(Packet.getLoginOut().get(getClass()));
DataTypeIO.writeVarInt(output, messageId); DataTypeIO.writeVarInt(output, messageId);
DataTypeIO.writeString(output, channel.toString(), StandardCharsets.UTF_8); DataTypeIO.writeString(output, channel.toString(), StandardCharsets.UTF_8);
output.write(data); output.write(data);
return buffer.toByteArray(); return buffer.toByteArray();
} }
} }

View File

@ -4,6 +4,6 @@ import java.io.IOException;
public abstract class PacketOut extends Packet { public abstract class PacketOut extends Packet {
public abstract byte[] serializePacket() throws IOException; public abstract byte[] serializePacket() throws IOException;
} }

View File

@ -1,25 +1,25 @@
package com.loohp.limbo.server.packets; package com.loohp.limbo.server.packets;
import com.loohp.limbo.utils.DataTypeIO;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import com.loohp.limbo.utils.DataTypeIO;
public class PacketPlayInChat extends PacketIn { public class PacketPlayInChat extends PacketIn {
private String message; private final String message;
public PacketPlayInChat(String message) { public PacketPlayInChat(String message) {
this.message = message; this.message = message;
} }
public PacketPlayInChat(DataInputStream in) throws IOException { public PacketPlayInChat(DataInputStream in) throws IOException {
this(DataTypeIO.readString(in, StandardCharsets.UTF_8)); this(DataTypeIO.readString(in, StandardCharsets.UTF_8));
} }
public String getMessage() { public String getMessage() {
return message; return message;
} }
} }

View File

@ -5,7 +5,7 @@ import java.io.IOException;
public class PacketPlayInHeldItemChange extends PacketIn { public class PacketPlayInHeldItemChange extends PacketIn {
private short slot; private final short slot;
public PacketPlayInHeldItemChange(short slot) { public PacketPlayInHeldItemChange(short slot) {
this.slot = slot; this.slot = slot;

View File

@ -5,18 +5,18 @@ import java.io.IOException;
public class PacketPlayInKeepAlive extends PacketIn { public class PacketPlayInKeepAlive extends PacketIn {
private long payload; private final long payload;
public PacketPlayInKeepAlive(long payload) { public PacketPlayInKeepAlive(long payload) {
this.payload = payload; this.payload = payload;
} }
public PacketPlayInKeepAlive(DataInputStream in) throws IOException { public PacketPlayInKeepAlive(DataInputStream in) throws IOException {
this(in.readLong()); this(in.readLong());
} }
public long getPayload() { public long getPayload() {
return payload; return payload;
} }
} }

View File

@ -1,36 +1,36 @@
package com.loohp.limbo.server.packets; 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.DataInputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import com.loohp.limbo.utils.DataTypeIO;
import com.loohp.limbo.utils.NamespacedKey;
public class PacketPlayInPluginMessaging extends PacketIn { public class PacketPlayInPluginMessaging extends PacketIn {
private NamespacedKey channel; private final NamespacedKey channel;
private byte[] data; private final byte[] data;
public PacketPlayInPluginMessaging(NamespacedKey channel, byte[] data) { public PacketPlayInPluginMessaging(NamespacedKey channel, byte[] data) {
this.channel = channel; this.channel = channel;
this.data = data; this.data = data;
} }
public PacketPlayInPluginMessaging(DataInputStream in, int packetLength, int packetId) throws IOException { public PacketPlayInPluginMessaging(DataInputStream in, int packetLength, int packetId) throws IOException {
String rawChannel = DataTypeIO.readString(in, StandardCharsets.UTF_8); String rawChannel = DataTypeIO.readString(in, StandardCharsets.UTF_8);
channel = new NamespacedKey(rawChannel); channel = new NamespacedKey(rawChannel);
int dataLength = packetLength - DataTypeIO.getVarIntLength(packetId) - DataTypeIO.getStringLength(rawChannel, StandardCharsets.UTF_8); int dataLength = packetLength - DataTypeIO.getVarIntLength(packetId) - DataTypeIO.getStringLength(rawChannel, StandardCharsets.UTF_8);
data = new byte[dataLength]; data = new byte[dataLength];
in.read(data); in.read(data);
} }
public NamespacedKey getChannel() { public NamespacedKey getChannel() {
return channel; return channel;
} }
public byte[] getData() { public byte[] getData() {
return data; return data;
} }
} }

View File

@ -5,36 +5,36 @@ import java.io.IOException;
public class PacketPlayInPosition extends PacketIn { public class PacketPlayInPosition extends PacketIn {
private double x; private final double x;
private double y; private final double y;
private double z; private final double z;
private boolean onGround; private final boolean onGround;
public PacketPlayInPosition(double x, double y, double z, boolean onGround) { public PacketPlayInPosition(double x, double y, double z, boolean onGround) {
this.x = x; this.x = x;
this.y = y; this.y = y;
this.z = z; this.z = z;
this.onGround = onGround; this.onGround = onGround;
} }
public PacketPlayInPosition(DataInputStream in) throws IOException { public PacketPlayInPosition(DataInputStream in) throws IOException {
this(in.readDouble(), in.readDouble(), in.readDouble(), in.readBoolean()); this(in.readDouble(), in.readDouble(), in.readDouble(), in.readBoolean());
} }
public double getX() { public double getX() {
return x; return x;
} }
public double getY() { public double getY() {
return y; return y;
} }
public double getZ() { public double getZ() {
return z; return z;
} }
public boolean onGround() { public boolean onGround() {
return onGround; return onGround;
} }
} }

View File

@ -5,48 +5,48 @@ import java.io.IOException;
public class PacketPlayInPositionAndLook extends PacketIn { public class PacketPlayInPositionAndLook extends PacketIn {
private double x; private final double x;
private double y; private final double y;
private double z; private final double z;
private float yaw; private final float yaw;
private float pitch; private final float pitch;
private boolean onGround; private final boolean onGround;
public PacketPlayInPositionAndLook(double x, double y, double z, float yaw, float pitch, boolean onGround) { public PacketPlayInPositionAndLook(double x, double y, double z, float yaw, float pitch, boolean onGround) {
this.x = x; this.x = x;
this.y = y; this.y = y;
this.z = z; this.z = z;
this.yaw = yaw; this.yaw = yaw;
this.pitch = pitch; this.pitch = pitch;
this.onGround = onGround; this.onGround = onGround;
} }
public PacketPlayInPositionAndLook(DataInputStream in) throws IOException { public PacketPlayInPositionAndLook(DataInputStream in) throws IOException {
this(in.readDouble(), in.readDouble(), in.readDouble(), in.readFloat(), in.readFloat(), in.readBoolean()); this(in.readDouble(), in.readDouble(), in.readDouble(), in.readFloat(), in.readFloat(), in.readBoolean());
} }
public double getX() { public double getX() {
return x; return x;
} }
public double getY() { public double getY() {
return y; return y;
} }
public double getZ() { public double getZ() {
return z; return z;
} }
public float getYaw() { public float getYaw() {
return yaw; return yaw;
} }
public float getPitch() { public float getPitch() {
return pitch; return pitch;
} }
public boolean onGround() { public boolean onGround() {
return onGround; return onGround;
} }
} }

View File

@ -5,30 +5,30 @@ import java.io.IOException;
public class PacketPlayInRotation extends PacketIn { public class PacketPlayInRotation extends PacketIn {
private float yaw; private final float yaw;
private float pitch; private final float pitch;
private boolean onGround; private final boolean onGround;
public PacketPlayInRotation(float yaw, float pitch, boolean onGround) { public PacketPlayInRotation(float yaw, float pitch, boolean onGround) {
this.yaw = yaw; this.yaw = yaw;
this.pitch = pitch; this.pitch = pitch;
this.onGround = onGround; this.onGround = onGround;
} }
public PacketPlayInRotation(DataInputStream in) throws IOException { public PacketPlayInRotation(DataInputStream in) throws IOException {
this(in.readFloat(), in.readFloat(), in.readBoolean()); this(in.readFloat(), in.readFloat(), in.readBoolean());
} }
public float getYaw() { public float getYaw() {
return yaw; return yaw;
} }
public float getPitch() { public float getPitch() {
return pitch; return pitch;
} }
public boolean onGround() { public boolean onGround() {
return onGround; return onGround;
} }
} }

View File

@ -1,31 +1,31 @@
package com.loohp.limbo.server.packets; package com.loohp.limbo.server.packets;
import com.loohp.limbo.utils.DataTypeIO;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import com.loohp.limbo.utils.DataTypeIO;
public class PacketPlayInTabComplete extends PacketIn { public class PacketPlayInTabComplete extends PacketIn {
private int id; private final int id;
private String text; private final String text;
public PacketPlayInTabComplete(int id, String text) { public PacketPlayInTabComplete(int id, String text) {
this.id = id; this.id = id;
this.text = text; this.text = text;
} }
public PacketPlayInTabComplete(DataInputStream in) throws IOException { public PacketPlayInTabComplete(DataInputStream in) throws IOException {
this(DataTypeIO.readVarInt(in), DataTypeIO.readString(in, StandardCharsets.UTF_8)); this(DataTypeIO.readVarInt(in), DataTypeIO.readString(in, StandardCharsets.UTF_8));
} }
public int getId() { public int getId() {
return id; return id;
} }
public String getText() { public String getText() {
return text; return text;
} }
} }

View File

@ -1,48 +1,48 @@
package com.loohp.limbo.server.packets; package com.loohp.limbo.server.packets;
import com.loohp.limbo.utils.DataTypeIO;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.UUID; import java.util.UUID;
import com.loohp.limbo.utils.DataTypeIO;
public class PacketPlayOutChat extends PacketOut { public class PacketPlayOutChat extends PacketOut {
private String json; private final String json;
private int position; private final int position;
private UUID sender; private final UUID sender;
public PacketPlayOutChat(String json, int position, UUID sender) { public PacketPlayOutChat(String json, int position, UUID sender) {
this.json = json; this.json = json;
this.position = position; this.position = position;
this.sender = sender; this.sender = sender;
} }
public String getJson() { public String getJson() {
return json; return json;
} }
public int getPosition() { public int getPosition() {
return position; return position;
} }
public UUID getSender() { public UUID getSender() {
return sender; return sender;
} }
@Override @Override
public byte[] serializePacket() throws IOException { public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer); DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass())); output.writeByte(Packet.getPlayOut().get(getClass()));
DataTypeIO.writeString(output, json, StandardCharsets.UTF_8); DataTypeIO.writeString(output, json, StandardCharsets.UTF_8);
output.writeByte(position); output.writeByte(position);
DataTypeIO.writeUUID(output, sender); DataTypeIO.writeUUID(output, sender);
return buffer.toByteArray(); return buffer.toByteArray();
} }
} }

View File

@ -6,25 +6,25 @@ import java.io.IOException;
public class PacketPlayOutDeclareCommands extends PacketOut { public class PacketPlayOutDeclareCommands extends PacketOut {
private byte[] data; private final byte[] data;
public PacketPlayOutDeclareCommands(byte[] data) { public PacketPlayOutDeclareCommands(byte[] data) {
this.data = data; this.data = data;
} }
public byte[] getData() { public byte[] getData() {
return data; return data;
} }
@Override @Override
public byte[] serializePacket() throws IOException { public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer); DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass())); output.writeByte(Packet.getPlayOut().get(getClass()));
output.write(data); output.write(data);
return buffer.toByteArray(); return buffer.toByteArray();
} }
} }

View File

@ -1,33 +1,33 @@
package com.loohp.limbo.server.packets; package com.loohp.limbo.server.packets;
import com.loohp.limbo.utils.DataTypeIO;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import com.loohp.limbo.utils.DataTypeIO;
public class PacketPlayOutDisconnect extends PacketOut { public class PacketPlayOutDisconnect extends PacketOut {
private String jsonReason; private final String jsonReason;
public PacketPlayOutDisconnect(String jsonReason) { public PacketPlayOutDisconnect(String jsonReason) {
this.jsonReason = jsonReason; this.jsonReason = jsonReason;
} }
public String getJsonReason() { public String getJsonReason() {
return jsonReason; return jsonReason;
} }
@Override @Override
public byte[] serializePacket() throws IOException { public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer); DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass())); output.writeByte(Packet.getPlayOut().get(getClass()));
DataTypeIO.writeString(output, jsonReason, StandardCharsets.UTF_8); DataTypeIO.writeString(output, jsonReason, StandardCharsets.UTF_8);
return buffer.toByteArray(); return buffer.toByteArray();
} }
} }

View File

@ -1,35 +1,35 @@
package com.loohp.limbo.server.packets; package com.loohp.limbo.server.packets;
import com.loohp.limbo.utils.DataTypeIO;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import com.loohp.limbo.utils.DataTypeIO;
public class PacketPlayOutEntityDestroy extends PacketOut { public class PacketPlayOutEntityDestroy extends PacketOut {
private int[] entityIds; private final int[] entityIds;
public PacketPlayOutEntityDestroy(int... entityIds) { public PacketPlayOutEntityDestroy(int... entityIds) {
this.entityIds = entityIds; this.entityIds = entityIds;
} }
public int[] getEntityIds() { public int[] getEntityIds() {
return entityIds; return entityIds;
} }
@Override @Override
public byte[] serializePacket() throws IOException { public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer); DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass())); output.writeByte(Packet.getPlayOut().get(getClass()));
DataTypeIO.writeVarInt(output, entityIds.length); DataTypeIO.writeVarInt(output, entityIds.length);
for (int id : entityIds) { for (int id : entityIds) {
DataTypeIO.writeVarInt(output, id); DataTypeIO.writeVarInt(output, id);
} }
return buffer.toByteArray(); return buffer.toByteArray();
} }
} }

View File

@ -1,156 +1,149 @@
package com.loohp.limbo.server.packets; 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.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Collection; import java.util.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry; 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 class PacketPlayOutEntityMetadata extends PacketOut {
public static final int END_OFF_METADATA = 0xff; public static final int END_OFF_METADATA = 0xff;
public boolean allFields;
public Field[] fields;
private final Entity entity;
private Entity entity; public PacketPlayOutEntityMetadata(Entity entity, boolean allFields, Field... fields) {
public boolean allFields; this.entity = entity;
public Field[] fields; this.allFields = allFields;
this.fields = fields;
}
public PacketPlayOutEntityMetadata(Entity entity, boolean allFields, Field... fields) { public PacketPlayOutEntityMetadata(Entity entity) {
this.entity = entity; this(entity, true);
this.allFields = allFields; }
this.fields = fields;
}
public PacketPlayOutEntityMetadata(Entity entity) { public Entity getEntity() {
this(entity, true); return entity;
} }
public Entity getEntity() { @Override
return entity; public byte[] serializePacket() throws IOException {
} ByteArrayOutputStream buffer = new ByteArrayOutputStream();
@Override DataOutputStream output = new DataOutputStream(buffer);
public byte[] serializePacket() throws IOException { output.writeByte(Packet.getPlayOut().get(getClass()));
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); DataTypeIO.writeVarInt(output, entity.getEntityId());
Collection<WatchableObject> watches;
if (allFields) {
watches = new HashSet<>(entity.getDataWatcher().getWatchableObjects().values());
} else {
watches = new HashSet<>();
Map<Field, WatchableObject> entries = entity.getDataWatcher().getWatchableObjects();
for (Field field : fields) {
WatchableObject watch = entries.get(field);
if (watch != null) {
watches.add(watch);
}
}
}
DataOutputStream output = new DataOutputStream(buffer); Map<Integer, Integer> bitmasks = new HashMap<>();
output.writeByte(Packet.getPlayOut().get(getClass())); Iterator<WatchableObject> itr = watches.iterator();
DataTypeIO.writeVarInt(output, entity.getEntityId()); while (itr.hasNext()) {
Collection<WatchableObject> watches; WatchableObject watch = itr.next();
if (allFields) { if (watch.isBitmask()) {
watches = new HashSet<>(entity.getDataWatcher().getWatchableObjects().values()); itr.remove();
} else { Integer bitmask = bitmasks.get(watch.getIndex());
watches = new HashSet<>(); if (bitmask == null) {
Map<Field, WatchableObject> entries = entity.getDataWatcher().getWatchableObjects(); bitmask = 0;
for (Field field : fields) { }
WatchableObject watch = entries.get(field); if ((boolean) watch.getValue()) {
if (watch != null) { bitmask |= watch.getBitmask();
watches.add(watch); } else {
} bitmask &= ~watch.getBitmask();
} }
} bitmasks.put(watch.getIndex(), bitmask);
}
}
for (Entry<Integer, Integer> entry : bitmasks.entrySet()) {
watches.add(new WatchableObject(entry.getValue().byteValue(), entry.getKey(), WatchableObjectType.BYTE));
}
Map<Integer, Integer> bitmasks = new HashMap<>(); for (WatchableObject watch : watches) {
Iterator<WatchableObject> itr = watches.iterator(); output.writeByte(watch.getIndex());
while (itr.hasNext()) { if (watch.isOptional()) {
WatchableObject watch = itr.next(); DataTypeIO.writeVarInt(output, watch.getType().getOptionalTypeId());
if (watch.isBitmask()) { output.writeBoolean(watch.getValue() != null);
itr.remove(); } else {
Integer bitmask = bitmasks.get(watch.getIndex()); DataTypeIO.writeVarInt(output, watch.getType().getTypeId());
if (bitmask == null) { }
bitmask = 0; if (!watch.isOptional() || watch.getValue() != null) {
} switch (watch.getType()) {
if ((boolean) watch.getValue()) { //case BLOCKID:
bitmask |= watch.getBitmask(); // break;
} else { case POSITION:
bitmask &= ~watch.getBitmask(); DataTypeIO.writeBlockPosition(output, (BlockPosition) watch.getValue());
} break;
bitmasks.put(watch.getIndex(), bitmask); case BOOLEAN:
} output.writeBoolean((boolean) watch.getValue());
} break;
for (Entry<Integer, Integer> entry : bitmasks.entrySet()) { case BYTE:
watches.add(new WatchableObject(entry.getValue().byteValue(), entry.getKey(), WatchableObjectType.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);
for (WatchableObject watch : watches) { return buffer.toByteArray();
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();
}
} }

View File

@ -6,32 +6,32 @@ import java.io.IOException;
public class PacketPlayOutGameState extends PacketOut { public class PacketPlayOutGameState extends PacketOut {
private int reason; private final int reason;
private float value; private final float value;
public PacketPlayOutGameState(int reason, float value) { public PacketPlayOutGameState(int reason, float value) {
this.reason = reason; this.reason = reason;
this.value = value; this.value = value;
} }
public int getReason() { public int getReason() {
return reason; return reason;
} }
public float getValue() { public float getValue() {
return value; return value;
} }
@Override @Override
public byte[] serializePacket() throws IOException { public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer); DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass())); output.writeByte(Packet.getPlayOut().get(getClass()));
output.writeByte(reason); output.writeByte(reason);
output.writeFloat(value); output.writeFloat(value);
return buffer.toByteArray(); return buffer.toByteArray();
} }
} }

View File

@ -6,25 +6,25 @@ import java.io.IOException;
public class PacketPlayOutKeepAlive extends PacketOut { public class PacketPlayOutKeepAlive extends PacketOut {
long payload; long payload;
public PacketPlayOutKeepAlive(long payload) { public PacketPlayOutKeepAlive(long payload) {
this.payload = payload; this.payload = payload;
} }
public long getPayload() { public long getPayload() {
return payload; return payload;
} }
@Override @Override
public byte[] serializePacket() throws IOException { public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer); DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass())); output.writeByte(Packet.getPlayOut().get(getClass()));
output.writeLong(payload); output.writeLong(payload);
return buffer.toByteArray(); return buffer.toByteArray();
} }
} }

View File

@ -1,111 +1,111 @@
package com.loohp.limbo.server.packets; package com.loohp.limbo.server.packets;
import com.loohp.limbo.utils.DataTypeIO;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import com.loohp.limbo.utils.DataTypeIO;
public class PacketPlayOutLightUpdate extends PacketOut { public class PacketPlayOutLightUpdate extends PacketOut {
private int chunkX; private final int chunkX;
private int chunkZ; private final int chunkZ;
private boolean trustEdges; private final boolean trustEdges;
private int skyLightBitMask; private int skyLightBitMask;
private int blockLightBitMask; private int blockLightBitMask;
private List<Byte[]> skylightArrays; private final List<Byte[]> skylightArrays;
private List<Byte[]> blocklightArrays; private final List<Byte[]> blocklightArrays;
public PacketPlayOutLightUpdate(int chunkX, int chunkZ, boolean trustEdges, List<Byte[]> skylightArrays, List<Byte[]> blocklightArrays) { public PacketPlayOutLightUpdate(int chunkX, int chunkZ, boolean trustEdges, List<Byte[]> skylightArrays, List<Byte[]> blocklightArrays) {
this.chunkX = chunkX; this.chunkX = chunkX;
this.chunkZ = chunkZ; this.chunkZ = chunkZ;
this.trustEdges = trustEdges; this.trustEdges = trustEdges;
this.skylightArrays = skylightArrays; this.skylightArrays = skylightArrays;
this.blocklightArrays = blocklightArrays; this.blocklightArrays = blocklightArrays;
skyLightBitMask = 0; skyLightBitMask = 0;
for (int i = Math.min(17, skylightArrays.size() - 1); i >= 0; i--) { for (int i = Math.min(17, skylightArrays.size() - 1); i >= 0; i--) {
skyLightBitMask = skyLightBitMask >> 1; skyLightBitMask = skyLightBitMask >> 1;
if (skylightArrays.get(i) != null) { if (skylightArrays.get(i) != null) {
skyLightBitMask |= 131072; skyLightBitMask |= 131072;
} }
} }
blockLightBitMask = 0; blockLightBitMask = 0;
for (int i = Math.min(17, blocklightArrays.size() - 1); i >= 0; i--) { for (int i = Math.min(17, blocklightArrays.size() - 1); i >= 0; i--) {
blockLightBitMask = blockLightBitMask >> 1; blockLightBitMask = blockLightBitMask >> 1;
if (blocklightArrays.get(i) != null) { if (blocklightArrays.get(i) != null) {
blockLightBitMask |= 131072; blockLightBitMask |= 131072;
} }
} }
} }
public int getChunkX() { public int getChunkX() {
return chunkX; return chunkX;
} }
public int getChunkZ() { public int getChunkZ() {
return chunkZ; return chunkZ;
} }
public boolean isTrustEdges() { public boolean isTrustEdges() {
return trustEdges; return trustEdges;
} }
public int getSkyLightBitMask() { public int getSkyLightBitMask() {
return skyLightBitMask; return skyLightBitMask;
} }
public int getBlockLightBitMask() { public int getBlockLightBitMask() {
return blockLightBitMask; return blockLightBitMask;
} }
public List<Byte[]> getSkylightArrays() { public List<Byte[]> getSkylightArrays() {
return skylightArrays; return skylightArrays;
} }
public List<Byte[]> getBlocklightArrays() { public List<Byte[]> getBlocklightArrays() {
return blocklightArrays; return blocklightArrays;
} }
@Override @Override
public byte[] serializePacket() throws IOException { public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer); DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass())); output.writeByte(Packet.getPlayOut().get(getClass()));
DataTypeIO.writeVarInt(output, chunkX); DataTypeIO.writeVarInt(output, chunkX);
DataTypeIO.writeVarInt(output, chunkZ); DataTypeIO.writeVarInt(output, chunkZ);
output.writeBoolean(trustEdges); output.writeBoolean(trustEdges);
DataTypeIO.writeVarInt(output, skyLightBitMask); DataTypeIO.writeVarInt(output, skyLightBitMask);
DataTypeIO.writeVarInt(output, blockLightBitMask); DataTypeIO.writeVarInt(output, blockLightBitMask);
DataTypeIO.writeVarInt(output, ~skyLightBitMask & 262143); DataTypeIO.writeVarInt(output, ~skyLightBitMask & 262143);
DataTypeIO.writeVarInt(output, ~blockLightBitMask & 262143); DataTypeIO.writeVarInt(output, ~blockLightBitMask & 262143);
for (int i = skylightArrays.size() - 1; i >= 0; i--) { for (int i = skylightArrays.size() - 1; i >= 0; i--) {
Byte[] array = skylightArrays.get(i); Byte[] array = skylightArrays.get(i);
if (array != null) { if (array != null) {
DataTypeIO.writeVarInt(output, 2048); DataTypeIO.writeVarInt(output, 2048);
//System.out.println(Arrays.toString(ArrayUtils.toPrimitive(array))); //System.out.println(Arrays.toString(ArrayUtils.toPrimitive(array)));
for (int u = 0; u < array.length; u++) { for (int u = 0; u < array.length; u++) {
output.writeByte(array[u]); output.writeByte(array[u]);
} }
} }
} }
for (int i = blocklightArrays.size() - 1; i >= 0; i--) { for (int i = blocklightArrays.size() - 1; i >= 0; i--) {
Byte[] array = blocklightArrays.get(i); Byte[] array = blocklightArrays.get(i);
if (array != null) { if (array != null) {
DataTypeIO.writeVarInt(output, 2048); DataTypeIO.writeVarInt(output, 2048);
//System.out.println(Arrays.toString(ArrayUtils.toPrimitive(array))); //System.out.println(Arrays.toString(ArrayUtils.toPrimitive(array)));
for (int u = 0; u < array.length; u++) { for (int u = 0; u < array.length; u++) {
output.writeByte(array[u]); output.writeByte(array[u]);
} }
} }
} }
return buffer.toByteArray(); return buffer.toByteArray();
} }
} }

View File

@ -1,146 +1,145 @@
package com.loohp.limbo.server.packets; 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.DataTypeIO;
import com.loohp.limbo.utils.GameMode; import com.loohp.limbo.utils.GameMode;
import com.loohp.limbo.utils.NamespacedKey; import com.loohp.limbo.utils.NamespacedKey;
import com.loohp.limbo.world.Environment; import com.loohp.limbo.world.Environment;
import com.loohp.limbo.world.World; import com.loohp.limbo.world.World;
import net.querz.nbt.tag.CompoundTag; import net.querz.nbt.tag.CompoundTag;
import net.querz.nbt.tag.ListTag; 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 { public class PacketPlayOutLogin extends PacketOut {
private int entityId; private final int entityId;
private boolean isHardcore; private final boolean isHardcore;
private GameMode gamemode; private final GameMode gamemode;
private String[] worldsNames; private final String[] worldsNames;
private CompoundTag dimensionCodec; private final CompoundTag dimensionCodec;
private Environment dimension; private final Environment dimension;
private String worldName; private final String worldName;
private long hashedSeed; private final long hashedSeed;
private byte maxPlayers; private final byte maxPlayers;
private int viewDistance; private final int viewDistance;
private boolean reducedDebugInfo; private final boolean reducedDebugInfo;
private boolean enableRespawnScreen; private final boolean enableRespawnScreen;
private boolean isDebug; private final boolean isDebug;
private boolean isFlat; private final boolean isFlat;
public PacketPlayOutLogin(int entityId, boolean isHardcore, GameMode gamemode, public PacketPlayOutLogin(int entityId, boolean isHardcore, GameMode gamemode,
String[] worldsNames, CompoundTag dimensionCodec, World world, long hashedSeed, String[] worldsNames, CompoundTag dimensionCodec, World world, long hashedSeed,
byte maxPlayers, int viewDistance, boolean reducedDebugInfo, boolean enableRespawnScreen, boolean isDebug, byte maxPlayers, int viewDistance, boolean reducedDebugInfo, boolean enableRespawnScreen, boolean isDebug,
boolean isFlat) { boolean isFlat) {
this.entityId = entityId; this.entityId = entityId;
this.isHardcore = isHardcore; this.isHardcore = isHardcore;
this.gamemode = gamemode; this.gamemode = gamemode;
this.worldsNames = worldsNames; this.worldsNames = worldsNames;
this.dimensionCodec = dimensionCodec; this.dimensionCodec = dimensionCodec;
this.dimension = world.getEnvironment(); this.dimension = world.getEnvironment();
this.worldName = new NamespacedKey(world.getName()).toString(); this.worldName = new NamespacedKey(world.getName()).toString();
this.hashedSeed = hashedSeed; this.hashedSeed = hashedSeed;
this.maxPlayers = maxPlayers; this.maxPlayers = maxPlayers;
this.viewDistance = viewDistance; this.viewDistance = viewDistance;
this.reducedDebugInfo = reducedDebugInfo; this.reducedDebugInfo = reducedDebugInfo;
this.enableRespawnScreen = enableRespawnScreen; this.enableRespawnScreen = enableRespawnScreen;
this.isDebug = isDebug; this.isDebug = isDebug;
this.isFlat = isFlat; this.isFlat = isFlat;
} }
public int getEntityId() { public int getEntityId() {
return entityId; return entityId;
} }
public boolean isHardcore() { public boolean isHardcore() {
return isHardcore; return isHardcore;
} }
public GameMode getGamemode() { public GameMode getGamemode() {
return gamemode; return gamemode;
} }
public String[] getWorldsNames() { public String[] getWorldsNames() {
return worldsNames; return worldsNames;
} }
public CompoundTag getDimensionCodec() { public CompoundTag getDimensionCodec() {
return dimensionCodec; return dimensionCodec;
} }
public Environment getDimension() { public Environment getDimension() {
return dimension; return dimension;
} }
public String getWorldName() { public String getWorldName() {
return worldName; return worldName;
} }
public long getHashedSeed() { public long getHashedSeed() {
return hashedSeed; return hashedSeed;
} }
public byte getMaxPlayers() { public byte getMaxPlayers() {
return maxPlayers; return maxPlayers;
} }
public int getViewDistance() { public int getViewDistance() {
return viewDistance; return viewDistance;
} }
public boolean isReducedDebugInfo() { public boolean isReducedDebugInfo() {
return reducedDebugInfo; return reducedDebugInfo;
} }
public boolean isEnableRespawnScreen() { public boolean isEnableRespawnScreen() {
return enableRespawnScreen; return enableRespawnScreen;
} }
public boolean isDebug() { public boolean isDebug() {
return isDebug; return isDebug;
} }
public boolean isFlat() { public boolean isFlat() {
return isFlat; return isFlat;
} }
@Override @Override
public byte[] serializePacket() throws IOException { public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer); DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass())); output.writeByte(Packet.getPlayOut().get(getClass()));
output.writeInt(entityId); output.writeInt(entityId);
output.writeBoolean(isHardcore); output.writeBoolean(isHardcore);
output.writeByte((byte) gamemode.getId()); output.writeByte((byte) gamemode.getId());
output.writeByte((byte) gamemode.getId()); output.writeByte((byte) gamemode.getId());
DataTypeIO.writeVarInt(output, worldsNames.length); DataTypeIO.writeVarInt(output, worldsNames.length);
for (int u = 0; u < worldsNames.length; u++) { for (int u = 0; u < worldsNames.length; u++) {
DataTypeIO.writeString(output, worldsNames[u], StandardCharsets.UTF_8); DataTypeIO.writeString(output, worldsNames[u], StandardCharsets.UTF_8);
} }
DataTypeIO.writeCompoundTag(output, dimensionCodec); DataTypeIO.writeCompoundTag(output, dimensionCodec);
CompoundTag tag = null; CompoundTag tag = null;
ListTag<CompoundTag> list = dimensionCodec.getCompoundTag("minecraft:dimension_type").getListTag("value").asCompoundTagList(); ListTag<CompoundTag> list = dimensionCodec.getCompoundTag("minecraft:dimension_type").getListTag("value").asCompoundTagList();
for (CompoundTag each : list) { for (CompoundTag each : list) {
if (each.getString("name").equals(dimension.getNamespacedKey().toString())) { if (each.getString("name").equals(dimension.getNamespacedKey().toString())) {
tag = each.getCompoundTag("element"); tag = each.getCompoundTag("element");
break; break;
} }
} }
DataTypeIO.writeCompoundTag(output, tag != null ? tag : list.get(0)); DataTypeIO.writeCompoundTag(output, tag != null ? tag : list.get(0));
DataTypeIO.writeString(output, worldName, StandardCharsets.UTF_8); DataTypeIO.writeString(output, worldName, StandardCharsets.UTF_8);
output.writeLong(hashedSeed); output.writeLong(hashedSeed);
DataTypeIO.writeVarInt(output, maxPlayers); DataTypeIO.writeVarInt(output, maxPlayers);
DataTypeIO.writeVarInt(output, viewDistance); DataTypeIO.writeVarInt(output, viewDistance);
output.writeBoolean(reducedDebugInfo); output.writeBoolean(reducedDebugInfo);
output.writeBoolean(enableRespawnScreen); output.writeBoolean(enableRespawnScreen);
output.writeBoolean(isDebug); output.writeBoolean(isDebug);
output.writeBoolean(isFlat); output.writeBoolean(isFlat);
return buffer.toByteArray(); return buffer.toByteArray();
} }
} }

View File

@ -1,116 +1,111 @@
package com.loohp.limbo.server.packets; 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.BitsUtils;
import com.loohp.limbo.utils.DataTypeIO; import com.loohp.limbo.utils.DataTypeIO;
import com.loohp.limbo.world.Environment; import com.loohp.limbo.world.Environment;
import com.loohp.limbo.world.GeneratedBlockDataMappings; import com.loohp.limbo.world.GeneratedBlockDataMappings;
import net.querz.mca.Chunk; import net.querz.mca.Chunk;
import net.querz.mca.Section; import net.querz.mca.Section;
import net.querz.nbt.tag.CompoundTag; import net.querz.nbt.tag.CompoundTag;
import net.querz.nbt.tag.ListTag; 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 { public class PacketPlayOutMapChunk extends PacketOut {
private int chunkX; private final int chunkX;
private int chunkZ; private final int chunkZ;
private Chunk chunk; private final Chunk chunk;
private Environment environment; private final Environment environment;
public PacketPlayOutMapChunk(int chunkX, int chunkZ, Chunk chunk, Environment environment) { public PacketPlayOutMapChunk(int chunkX, int chunkZ, Chunk chunk, Environment environment) {
this.chunkX = chunkX; this.chunkX = chunkX;
this.chunkZ = chunkZ; this.chunkZ = chunkZ;
this.chunk = chunk; this.chunk = chunk;
this.environment = environment; this.environment = environment;
} }
@Deprecated @Deprecated
public PacketPlayOutMapChunk(int chunkX, int chunkZ, Chunk chunk) { public PacketPlayOutMapChunk(int chunkX, int chunkZ, Chunk chunk) {
this(chunkZ, chunkZ, chunk, Environment.NORMAL); this(chunkZ, chunkZ, chunk, Environment.NORMAL);
} }
public Chunk getChunk() { public Chunk getChunk() {
return chunk; return chunk;
} }
public int getChunkX() { public int getChunkX() {
return chunkX; return chunkX;
} }
public int getChunkZ() { public int getChunkZ() {
return chunkZ; return chunkZ;
} }
public Environment getEnvironment() { public Environment getEnvironment() {
return environment; return environment;
} }
@Override @Override
public byte[] serializePacket() throws IOException { public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer); DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass())); output.writeByte(Packet.getPlayOut().get(getClass()));
output.writeInt(chunkX); output.writeInt(chunkX);
output.writeInt(chunkZ); output.writeInt(chunkZ);
output.writeBoolean(true); output.writeBoolean(true);
int bitmask = 0; int bitmask = 0;
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
Section section = chunk.getSection(i); Section section = chunk.getSection(i);
if (section != null) { if (section != null) {
bitmask = bitmask | (int) Math.pow(2, i); bitmask = bitmask | (int) Math.pow(2, i);
} }
} }
DataTypeIO.writeVarInt(output, bitmask); DataTypeIO.writeVarInt(output, bitmask);
DataTypeIO.writeCompoundTag(output, chunk.getHeightMaps()); DataTypeIO.writeCompoundTag(output, chunk.getHeightMaps());
DataTypeIO.writeVarInt(output, 1024); DataTypeIO.writeVarInt(output, 1024);
int biome; int biome;
if (environment.equals(Environment.END)) { if (environment.equals(Environment.END)) {
biome = 9; //the_end biome = 9; //the_end
} else if (environment.equals(Environment.NETHER)) { } else if (environment.equals(Environment.NETHER)) {
biome = 8; //nether_waste biome = 8; //nether_waste
} else if (environment.equals(Environment.NORMAL)) { } else if (environment.equals(Environment.NORMAL)) {
biome = 1; //plains biome = 1; //plains
} else { } else {
biome = 1; //plains biome = 1; //plains
} }
for (int i = 0; i < 1024; i++) { for (int i = 0; i < 1024; i++) {
DataTypeIO.writeVarInt(output, biome); DataTypeIO.writeVarInt(output, biome);
} }
ByteArrayOutputStream dataBuffer = new ByteArrayOutputStream(); ByteArrayOutputStream dataBuffer = new ByteArrayOutputStream();
DataOutputStream dataOut = new DataOutputStream(dataBuffer); DataOutputStream dataOut = new DataOutputStream(dataBuffer);
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
Section section = chunk.getSection(i); Section section = chunk.getSection(i);
if (section != null) { if (section != null) {
int counter = 0; int counter = 0;
for (int x = 0; x < 16; x++) { for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) { for (int z = 0; z < 16; z++) {
for (int y = 0; y < 16; y++) { for (int y = 0; y < 16; y++) {
CompoundTag tag = section.getBlockStateAt(x, y, z); CompoundTag tag = section.getBlockStateAt(x, y, z);
if (tag != null && !tag.getString("Name").equals("minecraft:air")) { if (tag != null && !tag.getString("Name").equals("minecraft:air")) {
counter++; counter++;
} }
} }
} }
} }
dataOut.writeShort(counter); dataOut.writeShort(counter);
int newBits = 32 - Integer.numberOfLeadingZeros(section.getPalette().size() - 1); int newBits = 32 - Integer.numberOfLeadingZeros(section.getPalette().size() - 1);
newBits = Math.max(newBits, 4); newBits = Math.max(newBits, 4);
//Limbo.getInstance().getConsole().sendMessage(i + " " + newBits); //Limbo.getInstance().getConsole().sendMessage(i + " " + newBits);
if (newBits <= 8) { if (newBits <= 8) {
/* /*
if (newBits == 4) { if (newBits == 4) {
dataOut.writeByte(4); dataOut.writeByte(4);
@ -120,92 +115,92 @@ public class PacketPlayOutMapChunk extends PacketOut {
dataOut.writeByte(8); dataOut.writeByte(8);
} }
*/ */
dataOut.writeByte(newBits); dataOut.writeByte(newBits);
DataTypeIO.writeVarInt(dataOut, section.getPalette().size()); DataTypeIO.writeVarInt(dataOut, section.getPalette().size());
//Limbo.getInstance().getConsole().sendMessage(section.getPalette().size()); //Limbo.getInstance().getConsole().sendMessage(section.getPalette().size());
Iterator<CompoundTag> itr1 = section.getPalette().iterator(); Iterator<CompoundTag> itr1 = section.getPalette().iterator();
//Limbo.getInstance().getConsole().sendMessage("Nonnull -> " + i + " " + newBits); //Limbo.getInstance().getConsole().sendMessage("Nonnull -> " + i + " " + newBits);
while (itr1.hasNext()) { while (itr1.hasNext()) {
CompoundTag tag = itr1.next(); CompoundTag tag = itr1.next();
DataTypeIO.writeVarInt(dataOut, GeneratedBlockDataMappings.getGlobalPaletteIDFromState(tag)); DataTypeIO.writeVarInt(dataOut, GeneratedBlockDataMappings.getGlobalPaletteIDFromState(tag));
//Limbo.getInstance().getConsole().sendMessage(tag + " -> " + GeneratedDataUtils.getGlobalPaletteIDFromState(tag)); //Limbo.getInstance().getConsole().sendMessage(tag + " -> " + GeneratedDataUtils.getGlobalPaletteIDFromState(tag));
} }
BitSet bits = BitSet.valueOf(section.getBlockStates()); BitSet bits = BitSet.valueOf(section.getBlockStates());
int shift = 64 % newBits; int shift = 64 % newBits;
int longsNeeded = (int) Math.ceil(4096 / (double) (64 / newBits)); int longsNeeded = (int) Math.ceil(4096 / (double) (64 / newBits));
for (int u = 64; u <= bits.length(); u += 64) { for (int u = 64; u <= bits.length(); u += 64) {
bits = BitsUtils.shiftAfter(bits, u - shift, shift); bits = BitsUtils.shiftAfter(bits, u - shift, shift);
} }
long[] formattedLongs = bits.toLongArray(); long[] formattedLongs = bits.toLongArray();
//Limbo.getInstance().getConsole().sendMessage(longsNeeded + ""); //Limbo.getInstance().getConsole().sendMessage(longsNeeded + "");
DataTypeIO.writeVarInt(dataOut, longsNeeded); DataTypeIO.writeVarInt(dataOut, longsNeeded);
for (int u = 0; u < longsNeeded; u++) { for (int u = 0; u < longsNeeded; u++) {
if (u < formattedLongs.length) { if (u < formattedLongs.length) {
dataOut.writeLong(formattedLongs[u]); dataOut.writeLong(formattedLongs[u]);
} else { } else {
dataOut.writeLong(0); dataOut.writeLong(0);
} }
//Limbo.getInstance().getConsole().sendMessage(Arrays.toString(section.getBlockStates())); //Limbo.getInstance().getConsole().sendMessage(Arrays.toString(section.getBlockStates()));
} }
} else { } else {
try { try {
dataOut.writeByte(15); dataOut.writeByte(15);
section.getBlockStates(); section.getBlockStates();
int longsNeeded = 1024; int longsNeeded = 1024;
List<Integer> list = new LinkedList<>(); List<Integer> list = new LinkedList<>();
for (int y = 0; y < 16; y++) { for (int y = 0; y < 16; y++) {
for (int z = 0; z < 16; z++) { for (int z = 0; z < 16; z++) {
for (int x = 0; x < 16; x++) { for (int x = 0; x < 16; x++) {
list.add(GeneratedBlockDataMappings.getGlobalPaletteIDFromState(section.getBlockStateAt(x, y, z))); list.add(GeneratedBlockDataMappings.getGlobalPaletteIDFromState(section.getBlockStateAt(x, y, z)));
} }
} }
} }
List<Long> globalLongs = new ArrayList<>(); List<Long> globalLongs = new ArrayList<>();
long currentLong = 0; long currentLong = 0;
int pos = 0; int pos = 0;
int u = 0; int u = 0;
while (pos < longsNeeded) { while (pos < longsNeeded) {
if (u == 3) { if (u == 3) {
globalLongs.add(currentLong); globalLongs.add(currentLong);
currentLong = 0; currentLong = 0;
u = 0; u = 0;
pos++; pos++;
} else { } else {
u++; u++;
} }
int id = list.isEmpty() ? 0 : list.remove(0); int id = list.isEmpty() ? 0 : list.remove(0);
currentLong = currentLong << 15; currentLong = currentLong << 15;
currentLong |= (long) id; currentLong |= id;
} }
DataTypeIO.writeVarInt(dataOut, longsNeeded); DataTypeIO.writeVarInt(dataOut, longsNeeded);
for (int j = 0; j < longsNeeded; j++) { for (int j = 0; j < longsNeeded; j++) {
if (j < globalLongs.size()) { if (j < globalLongs.size()) {
dataOut.writeLong(globalLongs.get(j)); dataOut.writeLong(globalLongs.get(j));
} else { } else {
dataOut.writeLong(0); dataOut.writeLong(0);
} }
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
} }
byte[] data = dataBuffer.toByteArray(); byte[] data = dataBuffer.toByteArray();
DataTypeIO.writeVarInt(output, data.length); DataTypeIO.writeVarInt(output, data.length);
output.write(data); output.write(data);
ListTag<CompoundTag> tileEntities = chunk.getTileEntities(); ListTag<CompoundTag> tileEntities = chunk.getTileEntities();
DataTypeIO.writeVarInt(output, tileEntities.size()); DataTypeIO.writeVarInt(output, tileEntities.size());
for (CompoundTag each : tileEntities) { for (CompoundTag each : tileEntities) {
DataTypeIO.writeCompoundTag(output, each); DataTypeIO.writeCompoundTag(output, each);
} }
return buffer.toByteArray(); return buffer.toByteArray();
} }
} }

View File

@ -6,61 +6,60 @@ import java.io.IOException;
public class PacketPlayOutPlayerAbilities extends PacketOut { public class PacketPlayOutPlayerAbilities extends PacketOut {
public enum PlayerAbilityFlags { private final PlayerAbilityFlags[] flags;
INVULNERABLE(0x01), private final float flySpeed;
FLY(0x02), private final float fieldOfField;
ALLOW_FLYING(0x04), public PacketPlayOutPlayerAbilities(float flySpeed, float fieldOfField, PlayerAbilityFlags... flags) {
CREATIVE(0x08); this.flags = flags;
this.flySpeed = flySpeed;
this.fieldOfField = fieldOfField;
}
int bitvalue; public PlayerAbilityFlags[] getFlags() {
return flags;
}
PlayerAbilityFlags(int bitvalue) { public float getFlySpeed() {
this.bitvalue = bitvalue; return flySpeed;
} }
public int getValue() { public float getFieldOfField() {
return bitvalue; return fieldOfField;
} }
}
private PlayerAbilityFlags[] flags; @Override
private float flySpeed; public byte[] serializePacket() throws IOException {
private float fieldOfField; ByteArrayOutputStream buffer = new ByteArrayOutputStream();
public PacketPlayOutPlayerAbilities(float flySpeed, float fieldOfField, PlayerAbilityFlags... flags) { DataOutputStream output = new DataOutputStream(buffer);
this.flags = flags; output.writeByte(Packet.getPlayOut().get(getClass()));
this.flySpeed = flySpeed; int value = 0;
this.fieldOfField = fieldOfField; for (PlayerAbilityFlags flag : flags) {
} value = value | flag.getValue();
}
public PlayerAbilityFlags[] getFlags() { output.writeByte(value);
return flags; output.writeFloat(flySpeed);
} output.writeFloat(fieldOfField);
public float getFlySpeed() { return buffer.toByteArray();
return flySpeed; }
}
public float getFieldOfField() { public enum PlayerAbilityFlags {
return fieldOfField; INVULNERABLE(0x01),
} FLY(0x02),
ALLOW_FLYING(0x04),
CREATIVE(0x08);
@Override int bitvalue;
public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer); PlayerAbilityFlags(int bitvalue) {
output.writeByte(Packet.getPlayOut().get(getClass())); this.bitvalue = bitvalue;
int value = 0; }
for (PlayerAbilityFlags flag : flags) {
value = value | flag.getValue();
}
output.writeByte(value); public int getValue() {
output.writeFloat(flySpeed); return bitvalue;
output.writeFloat(fieldOfField); }
}
return buffer.toByteArray();
}
} }

View File

@ -1,5 +1,9 @@
package com.loohp.limbo.server.packets; 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.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
@ -7,162 +11,157 @@ import java.nio.charset.StandardCharsets;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; 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 class PacketPlayOutPlayerInfo extends PacketOut {
public enum PlayerInfoAction { private final PlayerInfoAction action;
ADD_PLAYER(0), UPDATE_GAMEMODE(1), UPDATE_LATENCY(2), UPDATE_DISPLAY_NAME(3), REMOVE_PLAYER(4); 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) { public UUID getUuid() {
this.id = id; return uuid;
} }
public int getId() { public PlayerInfoData getData() {
return id; return data;
} }
}
private PlayerInfoAction action; @Override
private UUID uuid; public byte[] serializePacket() throws IOException {
private PlayerInfoData data; ByteArrayOutputStream buffer = new ByteArrayOutputStream();
public PacketPlayOutPlayerInfo(PlayerInfoAction action, UUID uuid, PlayerInfoData data) { DataOutputStream output = new DataOutputStream(buffer);
this.action = action; output.writeByte(Packet.getPlayOut().get(getClass()));
this.uuid = uuid; DataTypeIO.writeVarInt(output, action.getId());
this.data = data; DataTypeIO.writeVarInt(output, 1);
} DataTypeIO.writeUUID(output, uuid);
public PlayerInfoAction getAction() { switch (action) {
return 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 buffer.toByteArray();
return uuid; }
}
public PlayerInfoData getData() { public enum PlayerInfoAction {
return data; ADD_PLAYER(0), UPDATE_GAMEMODE(1), UPDATE_LATENCY(2), UPDATE_DISPLAY_NAME(3), REMOVE_PLAYER(4);
}
@Override int id;
public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer); PlayerInfoAction(int id) {
output.writeByte(Packet.getPlayOut().get(getClass())); this.id = id;
DataTypeIO.writeVarInt(output, action.getId()); }
DataTypeIO.writeVarInt(output, 1);
DataTypeIO.writeUUID(output, uuid);
switch (action) { public int getId() {
case ADD_PLAYER: return id;
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 static class PlayerInfoData {
public static class PlayerInfoData { public static class PlayerInfoDataAddPlayer extends PlayerInfoData {
public static class PlayerInfoDataAddPlayer extends PlayerInfoData { private final String name;
private final Optional<PlayerSkinProperty> skin;
private final GameMode gamemode;
private final int ping;
private final boolean hasDisplayName;
private final Optional<String> displayNameJson;
private String name; public PlayerInfoDataAddPlayer(String name, Optional<PlayerSkinProperty> skin, GameMode gamemode, int ping,
private Optional<PlayerSkinProperty> skin; boolean hasDisplayName, Optional<String> displayNameJson) {
private GameMode gamemode; this.name = name;
private int ping; this.skin = skin;
private boolean hasDisplayName; this.gamemode = gamemode;
private Optional<String> displayNameJson; this.ping = ping;
this.hasDisplayName = hasDisplayName;
this.displayNameJson = displayNameJson;
}
public PlayerInfoDataAddPlayer(String name, Optional<PlayerSkinProperty> skin, GameMode gamemode, int ping, public String getName() {
boolean hasDisplayName, Optional<String> displayNameJson) { return name;
this.name = name; }
this.skin = skin;
this.gamemode = gamemode;
this.ping = ping;
this.hasDisplayName = hasDisplayName;
this.displayNameJson = displayNameJson;
}
public String getName() { public Optional<PlayerSkinProperty> getProperty() {
return name; return skin;
} }
public Optional<PlayerSkinProperty> getProperty() { public GameMode getGamemode() {
return skin; return gamemode;
} }
public GameMode getGamemode() { public int getPing() {
return gamemode; return ping;
} }
public int getPing() { public boolean isHasDisplayName() {
return ping; return hasDisplayName;
} }
public boolean isHasDisplayName() { public Optional<String> getDisplayNameJson() {
return hasDisplayName; return displayNameJson;
} }
public Optional<String> getDisplayNameJson() { public static class PlayerSkinProperty {
return displayNameJson;
}
public static class PlayerSkinProperty { private final String skin;
private final String signature;
private String skin; public PlayerSkinProperty(String skin, String signature) {
private String signature; this.skin = skin;
this.signature = signature;
}
public PlayerSkinProperty(String skin, String signature) { public String getSkin() {
this.skin = skin; return skin;
this.signature = signature; }
}
public String getSkin() { public String getSignature() {
return skin; return signature;
} }
public String getSignature() { }
return signature;
}
} }
} }
}
} }

View File

@ -1,41 +1,41 @@
package com.loohp.limbo.server.packets; 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.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import com.loohp.limbo.utils.DataTypeIO;
import com.loohp.limbo.utils.NamespacedKey;
public class PacketPlayOutPluginMessaging extends PacketOut { public class PacketPlayOutPluginMessaging extends PacketOut {
private NamespacedKey channel; private final NamespacedKey channel;
private byte[] data; private final byte[] data;
public PacketPlayOutPluginMessaging(NamespacedKey channel, byte[] data) { public PacketPlayOutPluginMessaging(NamespacedKey channel, byte[] data) {
this.channel = channel; this.channel = channel;
this.data = data; this.data = data;
} }
public NamespacedKey getChannel() { public NamespacedKey getChannel() {
return channel; return channel;
} }
public byte[] getData() { public byte[] getData() {
return data; return data;
} }
@Override @Override
public byte[] serializePacket() throws IOException { public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer); DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass())); output.writeByte(Packet.getPlayOut().get(getClass()));
DataTypeIO.writeString(output, channel.toString(), StandardCharsets.UTF_8); DataTypeIO.writeString(output, channel.toString(), StandardCharsets.UTF_8);
output.write(data); output.write(data);
return buffer.toByteArray(); return buffer.toByteArray();
} }
} }

View File

@ -1,5 +1,7 @@
package com.loohp.limbo.server.packets; package com.loohp.limbo.server.packets;
import com.loohp.limbo.utils.DataTypeIO;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
@ -7,95 +9,92 @@ import java.util.Arrays;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.loohp.limbo.utils.DataTypeIO;
public class PacketPlayOutPositionAndLook extends PacketOut { public class PacketPlayOutPositionAndLook extends PacketOut {
public enum PlayerTeleportFlags { private final double x;
X((byte) 0x01), private final double y;
Y((byte) 0x02), private final double z;
Z((byte) 0x04), private final float yaw;
Y_ROT((byte) 0x08), private final float pitch;
X_ROT((byte) 0x10); private final Set<PlayerTeleportFlags> 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());
}
byte bit; public double getX() {
return x;
}
PlayerTeleportFlags(byte bit) { public double getY() {
this.bit = bit; return y;
} }
public byte getBit() { public double getZ() {
return bit; return z;
} }
}
private double x; public float getYaw() {
private double y; return yaw;
private double z; }
private float yaw;
private float pitch;
private Set<PlayerTeleportFlags> flags;
private int teleportId;
public PacketPlayOutPositionAndLook(double x, double y, double z, float yaw, float pitch, int teleportId, PlayerTeleportFlags... flags) { public float getPitch() {
this.x = x; return pitch;
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() { public Set<PlayerTeleportFlags> getFlags() {
return x; return flags;
} }
public double getY() { public int getTeleportId() {
return y; return teleportId;
} }
public double getZ() { @Override
return z; public byte[] serializePacket() throws IOException {
} ByteArrayOutputStream buffer = new ByteArrayOutputStream();
public float getYaw() { DataOutputStream output = new DataOutputStream(buffer);
return yaw; output.writeByte(Packet.getPlayOut().get(getClass()));
} output.writeDouble(x);
output.writeDouble(y);
output.writeDouble(z);
output.writeFloat(yaw);
output.writeFloat(pitch);
public float getPitch() { byte flag = 0;
return pitch; for (PlayerTeleportFlags each : flags) {
} flag = (byte) (flag | each.getBit());
}
public Set<PlayerTeleportFlags> getFlags() { output.writeByte(flag);
return flags; DataTypeIO.writeVarInt(output, teleportId);
}
public int getTeleportId() { return buffer.toByteArray();
return teleportId; }
}
@Override public enum PlayerTeleportFlags {
public byte[] serializePacket() throws IOException { X((byte) 0x01),
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); Y((byte) 0x02),
Z((byte) 0x04),
Y_ROT((byte) 0x08),
X_ROT((byte) 0x10);
DataOutputStream output = new DataOutputStream(buffer); byte bit;
output.writeByte(Packet.getPlayOut().get(getClass()));
output.writeDouble(x);
output.writeDouble(y);
output.writeDouble(z);
output.writeFloat(yaw);
output.writeFloat(pitch);
byte flag = 0; PlayerTeleportFlags(byte bit) {
for (PlayerTeleportFlags each : flags) { this.bit = bit;
flag = (byte) (flag | each.getBit()); }
}
output.writeByte(flag); public byte getBit() {
DataTypeIO.writeVarInt(output, teleportId); return bit;
}
return buffer.toByteArray(); }
}
} }

View File

@ -1,97 +1,96 @@
package com.loohp.limbo.server.packets; 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.DataTypeIO;
import com.loohp.limbo.utils.GameMode; import com.loohp.limbo.utils.GameMode;
import com.loohp.limbo.utils.NamespacedKey; import com.loohp.limbo.utils.NamespacedKey;
import com.loohp.limbo.world.Environment; import com.loohp.limbo.world.Environment;
import com.loohp.limbo.world.World; import com.loohp.limbo.world.World;
import net.querz.nbt.tag.CompoundTag; import net.querz.nbt.tag.CompoundTag;
import net.querz.nbt.tag.ListTag; 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 { public class PacketPlayOutRespawn extends PacketOut {
private Environment dimension; private final Environment dimension;
private String worldName; private final String worldName;
private CompoundTag dimensionCodec; private final CompoundTag dimensionCodec;
private long hashedSeed; private final long hashedSeed;
private GameMode gamemode; private final GameMode gamemode;
private boolean isDebug; private final boolean isDebug;
private boolean isFlat; private final boolean isFlat;
private boolean copyMetaData; private final boolean copyMetaData;
public PacketPlayOutRespawn(World world, CompoundTag dimensionCodec, long hashedSeed, GameMode gamemode, boolean isDebug, boolean isFlat, boolean copyMetaData) { public PacketPlayOutRespawn(World world, CompoundTag dimensionCodec, long hashedSeed, GameMode gamemode, boolean isDebug, boolean isFlat, boolean copyMetaData) {
this.dimension = world.getEnvironment(); this.dimension = world.getEnvironment();
this.dimensionCodec = dimensionCodec; this.dimensionCodec = dimensionCodec;
this.worldName = new NamespacedKey(world.getName()).toString(); this.worldName = new NamespacedKey(world.getName()).toString();
this.hashedSeed = hashedSeed; this.hashedSeed = hashedSeed;
this.gamemode = gamemode; this.gamemode = gamemode;
this.isDebug = isDebug; this.isDebug = isDebug;
this.isFlat = isFlat; this.isFlat = isFlat;
this.copyMetaData = copyMetaData; this.copyMetaData = copyMetaData;
} }
public CompoundTag getDimensionCodec() { public CompoundTag getDimensionCodec() {
return dimensionCodec; return dimensionCodec;
} }
public Environment getDimension() { public Environment getDimension() {
return dimension; return dimension;
} }
public String getWorldName() { public String getWorldName() {
return worldName; return worldName;
} }
public long getHashedSeed() { public long getHashedSeed() {
return hashedSeed; return hashedSeed;
} }
public GameMode getGamemode() { public GameMode getGamemode() {
return gamemode; return gamemode;
} }
public boolean isDebug() { public boolean isDebug() {
return isDebug; return isDebug;
} }
public boolean isFlat() { public boolean isFlat() {
return isFlat; return isFlat;
} }
public boolean isCopyMetaData() { public boolean isCopyMetaData() {
return copyMetaData; return copyMetaData;
} }
@Override @Override
public byte[] serializePacket() throws IOException { public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer); DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass())); output.writeByte(Packet.getPlayOut().get(getClass()));
CompoundTag tag = null; CompoundTag tag = null;
ListTag<CompoundTag> list = dimensionCodec.getCompoundTag("minecraft:dimension_type").getListTag("value").asCompoundTagList(); ListTag<CompoundTag> list = dimensionCodec.getCompoundTag("minecraft:dimension_type").getListTag("value").asCompoundTagList();
for (CompoundTag each : list) { for (CompoundTag each : list) {
if (each.getString("name").equals(dimension.getNamespacedKey().toString())) { if (each.getString("name").equals(dimension.getNamespacedKey().toString())) {
tag = each.getCompoundTag("element"); tag = each.getCompoundTag("element");
break; break;
} }
} }
DataTypeIO.writeCompoundTag(output, tag != null ? tag : list.get(0)); DataTypeIO.writeCompoundTag(output, tag != null ? tag : list.get(0));
DataTypeIO.writeString(output, worldName, StandardCharsets.UTF_8); DataTypeIO.writeString(output, worldName, StandardCharsets.UTF_8);
output.writeLong(hashedSeed); output.writeLong(hashedSeed);
output.writeByte((byte) gamemode.getId()); output.writeByte((byte) gamemode.getId());
output.writeByte((byte) gamemode.getId()); output.writeByte((byte) gamemode.getId());
output.writeBoolean(isDebug); output.writeBoolean(isDebug);
output.writeBoolean(isFlat); output.writeBoolean(isFlat);
output.writeBoolean(copyMetaData); output.writeBoolean(copyMetaData);
return buffer.toByteArray(); return buffer.toByteArray();
} }
} }

View File

@ -1,111 +1,111 @@
package com.loohp.limbo.server.packets; 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.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.UUID; import java.util.UUID;
import com.loohp.limbo.entity.EntityType;
import com.loohp.limbo.utils.DataTypeIO;
public class PacketPlayOutSpawnEntity extends PacketOut { public class PacketPlayOutSpawnEntity extends PacketOut {
private int entityId; private final int entityId;
private UUID uuid; private final UUID uuid;
private EntityType type; private final EntityType type;
private double x; private final double x;
private double y; private final double y;
private double z; private final double z;
private float pitch; private final float pitch;
private float yaw; private final float yaw;
private int data; private final int data;
private short velocityX; private final short velocityX;
private short velocityY; private final short velocityY;
private short velocityZ; private final 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) { 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.entityId = entityId;
this.uuid = uuid; this.uuid = uuid;
this.type = type; this.type = type;
this.x = x; this.x = x;
this.y = y; this.y = y;
this.z = z; this.z = z;
this.pitch = pitch; this.pitch = pitch;
this.yaw = yaw; this.yaw = yaw;
this.data = 0; //TO-DO this.data = 0; //TO-DO
this.velocityX = velocityX; this.velocityX = velocityX;
this.velocityY = velocityY; this.velocityY = velocityY;
this.velocityZ = velocityZ; this.velocityZ = velocityZ;
} }
public int getEntityId() { public int getEntityId() {
return entityId; return entityId;
} }
public UUID getUuid() { public UUID getUuid() {
return uuid; return uuid;
} }
public EntityType getType() { public EntityType getType() {
return type; return type;
} }
public double getX() { public double getX() {
return x; return x;
} }
public double getY() { public double getY() {
return y; return y;
} }
public double getZ() { public double getZ() {
return z; return z;
} }
public float getPitch() { public float getPitch() {
return pitch; return pitch;
} }
public float getYaw() { public float getYaw() {
return yaw; return yaw;
} }
public int getData() { public int getData() {
return data; return data;
} }
public short getVelocityX() { public short getVelocityX() {
return velocityX; return velocityX;
} }
public short getVelocityY() { public short getVelocityY() {
return velocityY; return velocityY;
} }
public short getVelocityZ() { public short getVelocityZ() {
return velocityZ; return velocityZ;
} }
@Override @Override
public byte[] serializePacket() throws IOException { public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer); DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass())); output.writeByte(Packet.getPlayOut().get(getClass()));
DataTypeIO.writeVarInt(output, entityId); DataTypeIO.writeVarInt(output, entityId);
DataTypeIO.writeUUID(output, uuid); DataTypeIO.writeUUID(output, uuid);
DataTypeIO.writeVarInt(output, type.getTypeId()); DataTypeIO.writeVarInt(output, type.getTypeId());
output.writeDouble(x); output.writeDouble(x);
output.writeDouble(y); output.writeDouble(y);
output.writeDouble(z); output.writeDouble(z);
output.writeByte((byte) (int) (pitch * 256.0F / 360.0F)); output.writeByte((byte) (int) (pitch * 256.0F / 360.0F));
output.writeByte((byte) (int) (yaw * 256.0F / 360.0F)); output.writeByte((byte) (int) (yaw * 256.0F / 360.0F));
output.writeInt(data); output.writeInt(data);
output.writeShort((int) (velocityX * 8000)); output.writeShort(velocityX * 8000);
output.writeShort((int) (velocityY * 8000)); output.writeShort(velocityY * 8000);
output.writeShort((int) (velocityZ * 8000)); output.writeShort(velocityZ * 8000);
return buffer.toByteArray(); return buffer.toByteArray();
} }
} }

View File

@ -1,111 +1,111 @@
package com.loohp.limbo.server.packets; 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.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.UUID; import java.util.UUID;
import com.loohp.limbo.entity.EntityType;
import com.loohp.limbo.utils.DataTypeIO;
public class PacketPlayOutSpawnEntityLiving extends PacketOut { public class PacketPlayOutSpawnEntityLiving extends PacketOut {
private int entityId; private final int entityId;
private UUID uuid; private final UUID uuid;
private EntityType type; private final EntityType type;
private double x; private final double x;
private double y; private final double y;
private double z; private final double z;
private float yaw; private final float yaw;
private float pitch; private final float pitch;
private float headPitch; private final float headPitch;
private short velocityX; private final short velocityX;
private short velocityY; private final short velocityY;
private short velocityZ; private final 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) { 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.entityId = entityId;
this.uuid = uuid; this.uuid = uuid;
this.type = type; this.type = type;
this.x = x; this.x = x;
this.y = y; this.y = y;
this.z = z; this.z = z;
this.yaw = yaw; this.yaw = yaw;
this.pitch = pitch; this.pitch = pitch;
this.headPitch = headPitch; this.headPitch = headPitch;
this.velocityX = velocityX; this.velocityX = velocityX;
this.velocityY = velocityY; this.velocityY = velocityY;
this.velocityZ = velocityZ; this.velocityZ = velocityZ;
} }
public int getEntityId() { public int getEntityId() {
return entityId; return entityId;
} }
public UUID getUuid() { public UUID getUuid() {
return uuid; return uuid;
} }
public EntityType getType() { public EntityType getType() {
return type; return type;
} }
public double getX() { public double getX() {
return x; return x;
} }
public double getY() { public double getY() {
return y; return y;
} }
public double getZ() { public double getZ() {
return z; return z;
} }
public float getYaw() { public float getYaw() {
return yaw; return yaw;
} }
public float getPitch() { public float getPitch() {
return pitch; return pitch;
} }
public float getHeadPitch() { public float getHeadPitch() {
return headPitch; return headPitch;
} }
public short getVelocityX() { public short getVelocityX() {
return velocityX; return velocityX;
} }
public short getVelocityY() { public short getVelocityY() {
return velocityY; return velocityY;
} }
public short getVelocityZ() { public short getVelocityZ() {
return velocityZ; return velocityZ;
} }
@Override @Override
public byte[] serializePacket() throws IOException { public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer); DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass())); output.writeByte(Packet.getPlayOut().get(getClass()));
DataTypeIO.writeVarInt(output, entityId); DataTypeIO.writeVarInt(output, entityId);
DataTypeIO.writeUUID(output, uuid); DataTypeIO.writeUUID(output, uuid);
DataTypeIO.writeVarInt(output, type.getTypeId()); DataTypeIO.writeVarInt(output, type.getTypeId());
output.writeDouble(x); output.writeDouble(x);
output.writeDouble(y); output.writeDouble(y);
output.writeDouble(z); output.writeDouble(z);
output.writeByte((byte) (int) (yaw * 256.0F / 360.0F)); output.writeByte((byte) (int) (yaw * 256.0F / 360.0F));
output.writeByte((byte) (int) (pitch * 256.0F / 360.0F)); output.writeByte((byte) (int) (pitch * 256.0F / 360.0F));
output.writeByte((byte) (int) (headPitch * 256.0F / 360.0F)); output.writeByte((byte) (int) (headPitch * 256.0F / 360.0F));
output.writeShort((int) (velocityX * 8000)); output.writeShort(velocityX * 8000);
output.writeShort((int) (velocityY * 8000)); output.writeShort(velocityY * 8000);
output.writeShort((int) (velocityZ * 8000)); output.writeShort(velocityZ * 8000);
return buffer.toByteArray(); return buffer.toByteArray();
} }
} }

View File

@ -1,32 +1,32 @@
package com.loohp.limbo.server.packets; 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.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import com.loohp.limbo.utils.DataTypeIO;
import com.loohp.limbo.world.BlockPosition;
public class PacketPlayOutSpawnPosition extends PacketOut { public class PacketPlayOutSpawnPosition extends PacketOut {
private BlockPosition position; private final BlockPosition position;
public PacketPlayOutSpawnPosition(BlockPosition position) { public PacketPlayOutSpawnPosition(BlockPosition position) {
this.position = position; this.position = position;
} }
public BlockPosition getPosition() { public BlockPosition getPosition() {
return position; return position;
} }
public byte[] serializePacket() throws IOException { public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer); DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass())); output.writeByte(Packet.getPlayOut().get(getClass()));
DataTypeIO.writeBlockPosition(output, position); DataTypeIO.writeBlockPosition(output, position);
return buffer.toByteArray(); return buffer.toByteArray();
} }
} }

View File

@ -1,88 +1,87 @@
package com.loohp.limbo.server.packets; 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.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Optional; 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 { public class PacketPlayOutTabComplete extends PacketOut {
private int id; private final int id;
private int start; private final int start;
private int length; private final int length;
private TabCompleteMatches[] matches; private final TabCompleteMatches[] matches;
public PacketPlayOutTabComplete(int id, int start, int length, TabCompleteMatches... matches) { public PacketPlayOutTabComplete(int id, int start, int length, TabCompleteMatches... matches) {
this.id = id; this.id = id;
this.start = start; this.start = start;
this.length = length; this.length = length;
this.matches = matches; this.matches = matches;
} }
public int getId() { public int getId() {
return id; return id;
} }
public int getStart() { public int getStart() {
return start; return start;
} }
public int getLength() { public int getLength() {
return length; return length;
} }
public TabCompleteMatches[] getMatches() { public TabCompleteMatches[] getMatches() {
return matches; return matches;
} }
@Override @Override
public byte[] serializePacket() throws IOException { public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer); DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass())); output.writeByte(Packet.getPlayOut().get(getClass()));
DataTypeIO.writeVarInt(output, id); DataTypeIO.writeVarInt(output, id);
DataTypeIO.writeVarInt(output, start); DataTypeIO.writeVarInt(output, start);
DataTypeIO.writeVarInt(output, length); DataTypeIO.writeVarInt(output, length);
DataTypeIO.writeVarInt(output, matches.length); DataTypeIO.writeVarInt(output, matches.length);
for (TabCompleteMatches match : matches) { for (TabCompleteMatches match : matches) {
DataTypeIO.writeString(output, match.getMatch(), StandardCharsets.UTF_8); DataTypeIO.writeString(output, match.getMatch(), StandardCharsets.UTF_8);
if (match.getTooltip().isPresent()) { if (match.getTooltip().isPresent()) {
output.writeBoolean(true); output.writeBoolean(true);
DataTypeIO.writeString(output, ComponentSerializer.toString(match.getTooltip().get()), StandardCharsets.UTF_8); DataTypeIO.writeString(output, ComponentSerializer.toString(match.getTooltip().get()), StandardCharsets.UTF_8);
} else { } else {
output.writeBoolean(false); output.writeBoolean(false);
} }
} }
return buffer.toByteArray(); return buffer.toByteArray();
} }
public static class TabCompleteMatches { public static class TabCompleteMatches {
private String match; private final String match;
private Optional<BaseComponent[]> tooltip; private final Optional<BaseComponent[]> tooltip;
public TabCompleteMatches(String match, BaseComponent... tooltip) { public TabCompleteMatches(String match, BaseComponent... tooltip) {
this.match = match; this.match = match;
this.tooltip = tooltip.length > 0 ? Optional.of(tooltip) : Optional.empty(); this.tooltip = tooltip.length > 0 ? Optional.of(tooltip) : Optional.empty();
} }
public String getMatch() { public String getMatch() {
return match; return match;
} }
public Optional<BaseComponent[]> getTooltip() { public Optional<BaseComponent[]> getTooltip() {
return tooltip; return tooltip;
} }
} }
} }

View File

@ -6,32 +6,32 @@ import java.io.IOException;
public class PacketPlayOutUnloadChunk extends PacketOut { public class PacketPlayOutUnloadChunk extends PacketOut {
private int chunkX; private final int chunkX;
private int chunkZ; private final int chunkZ;
public PacketPlayOutUnloadChunk(int chunkX, int chunkZ) { public PacketPlayOutUnloadChunk(int chunkX, int chunkZ) {
this.chunkX = chunkX; this.chunkX = chunkX;
this.chunkZ = chunkZ; this.chunkZ = chunkZ;
} }
public int getChunkX() { public int getChunkX() {
return chunkX; return chunkX;
} }
public int getChunkZ() { public int getChunkZ() {
return chunkZ; return chunkZ;
} }
@Override @Override
public byte[] serializePacket() throws IOException { public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer); DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass())); output.writeByte(Packet.getPlayOut().get(getClass()));
output.writeInt(chunkX); output.writeInt(chunkX);
output.writeInt(chunkZ); output.writeInt(chunkZ);
return buffer.toByteArray(); return buffer.toByteArray();
} }
} }

View File

@ -1,39 +1,39 @@
package com.loohp.limbo.server.packets; package com.loohp.limbo.server.packets;
import com.loohp.limbo.utils.DataTypeIO;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import com.loohp.limbo.utils.DataTypeIO;
public class PacketPlayOutUpdateViewPosition extends PacketOut { public class PacketPlayOutUpdateViewPosition extends PacketOut {
private int chunkX; private final int chunkX;
private int chunkZ; private final int chunkZ;
public PacketPlayOutUpdateViewPosition(int chunkX, int chunkZ) { public PacketPlayOutUpdateViewPosition(int chunkX, int chunkZ) {
this.chunkX = chunkX; this.chunkX = chunkX;
this.chunkZ = chunkZ; this.chunkZ = chunkZ;
} }
public int getChunkX() { public int getChunkX() {
return chunkX; return chunkX;
} }
public int getChunkZ() { public int getChunkZ() {
return chunkZ; return chunkZ;
} }
@Override @Override
public byte[] serializePacket() throws IOException { public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer); DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass())); output.writeByte(Packet.getPlayOut().get(getClass()));
DataTypeIO.writeVarInt(output, chunkX); DataTypeIO.writeVarInt(output, chunkX);
DataTypeIO.writeVarInt(output, chunkZ); DataTypeIO.writeVarInt(output, chunkZ);
return buffer.toByteArray(); return buffer.toByteArray();
} }
} }

View File

@ -5,18 +5,18 @@ import java.io.IOException;
public class PacketStatusInPing extends PacketIn { public class PacketStatusInPing extends PacketIn {
private long payload; private final long payload;
public PacketStatusInPing(long payload) { public PacketStatusInPing(long payload) {
this.payload = payload; this.payload = payload;
} }
public PacketStatusInPing(DataInputStream in) throws IOException { public PacketStatusInPing(DataInputStream in) throws IOException {
this(in.readLong()); this(in.readLong());
} }
public long getPayload() { public long getPayload() {
return payload; return payload;
} }
} }

View File

@ -4,12 +4,12 @@ import java.io.DataInputStream;
public class PacketStatusInRequest extends PacketIn { public class PacketStatusInRequest extends PacketIn {
public PacketStatusInRequest() { public PacketStatusInRequest() {
} }
public PacketStatusInRequest(DataInputStream in) { public PacketStatusInRequest(DataInputStream in) {
this(); this();
} }
} }

View File

@ -6,25 +6,25 @@ import java.io.IOException;
public class PacketStatusOutPong extends PacketOut { public class PacketStatusOutPong extends PacketOut {
private long payload; private final long payload;
public PacketStatusOutPong(long payload) { public PacketStatusOutPong(long payload) {
this.payload = payload; this.payload = payload;
} }
public long getPayload() { public long getPayload() {
return payload; return payload;
} }
@Override @Override
public byte[] serializePacket() throws IOException { public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer); DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getStatusOut().get(getClass())); output.writeByte(Packet.getStatusOut().get(getClass()));
output.writeLong(payload); output.writeLong(payload);
return buffer.toByteArray(); return buffer.toByteArray();
} }
} }

View File

@ -1,33 +1,33 @@
package com.loohp.limbo.server.packets; package com.loohp.limbo.server.packets;
import com.loohp.limbo.utils.DataTypeIO;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import com.loohp.limbo.utils.DataTypeIO;
public class PacketStatusOutResponse extends PacketOut { public class PacketStatusOutResponse extends PacketOut {
private String json; private final String json;
public PacketStatusOutResponse(String json) { public PacketStatusOutResponse(String json) {
this.json = json; this.json = json;
} }
public String getJson() { public String getJson() {
return json; return json;
} }
@Override @Override
public byte[] serializePacket() throws IOException { public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer); DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getStatusOut().get(getClass())); output.writeByte(Packet.getStatusOut().get(getClass()));
DataTypeIO.writeString(output, json, StandardCharsets.UTF_8); DataTypeIO.writeString(output, json, StandardCharsets.UTF_8);
return buffer.toByteArray(); return buffer.toByteArray();
} }
} }

View File

@ -7,23 +7,23 @@ import java.util.List;
public class BitsUtils { public class BitsUtils {
public static BitSet shiftAfter(BitSet bitset, int from, int shift) { public static BitSet shiftAfter(BitSet bitset, int from, int shift) {
BitSet subset = bitset.get(from, bitset.length()); BitSet subset = bitset.get(from, bitset.length());
for (int i = 0; i < subset.length(); i++) { for (int i = 0; i < subset.length(); i++) {
bitset.set(from + shift + i, subset.get(i)); bitset.set(from + shift + i, subset.get(i));
} }
if (shift > 0) { if (shift > 0) {
for (int i = 0; i < shift; i++) { for (int i = 0; i < shift; i++) {
bitset.set(from + i, false); bitset.set(from + i, false);
} }
} }
return bitset; return bitset;
} }
public static String toLongString(BitSet bitset) { public static String toLongString(BitSet bitset) {
List<String> list = new ArrayList<>(); List<String> list = new ArrayList<>();
for (long l : bitset.toLongArray()) { for (long l : bitset.toLongArray()) {
list.add(Long.toBinaryString(l)); list.add(Long.toBinaryString(l));
} }
return Arrays.toString(list.toArray()); return Arrays.toString(list.toArray());
} }

View File

@ -1,58 +1,58 @@
package com.loohp.limbo.utils; 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.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.UUID; 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 class BungeeLoginMessageUtils {
public static void sendUUIDRequest(DataOutputStream output) throws IOException { public static void sendUUIDRequest(DataOutputStream output) throws IOException {
ByteArrayDataOutput out = ByteStreams.newDataOutput(); ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF("UUID"); out.writeUTF("UUID");
PacketPlayOutPluginMessaging packet = new PacketPlayOutPluginMessaging(new NamespacedKey("bungeecord", "main"), out.toByteArray()); PacketPlayOutPluginMessaging packet = new PacketPlayOutPluginMessaging(new NamespacedKey("bungeecord", "main"), out.toByteArray());
byte[] packetByte = packet.serializePacket(); byte[] packetByte = packet.serializePacket();
DataTypeIO.writeVarInt(output, packetByte.length); DataTypeIO.writeVarInt(output, packetByte.length);
output.write(packetByte); output.write(packetByte);
} }
public static UUID readUUIDResponse(byte[] data) { public static UUID readUUIDResponse(byte[] data) {
ByteArrayDataInput in = ByteStreams.newDataInput(data); ByteArrayDataInput in = ByteStreams.newDataInput(data);
String subchannel = in.readUTF(); String subchannel = in.readUTF();
if (subchannel.equals("UUID")) { if (subchannel.equals("UUID")) {
return UUID.fromString(in.readUTF()); return UUID.fromString(in.readUTF());
} else { } else {
throw new RuntimeException("Bungeecord Message receieved is not an IP"); throw new RuntimeException("Bungeecord Message receieved is not an IP");
} }
} }
public static void sendIPRequest(DataOutputStream output) throws IOException { public static void sendIPRequest(DataOutputStream output) throws IOException {
ByteArrayDataOutput out = ByteStreams.newDataOutput(); ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF("IP"); out.writeUTF("IP");
PacketPlayOutPluginMessaging packet = new PacketPlayOutPluginMessaging(new NamespacedKey("bungeecord", "main"), out.toByteArray()); PacketPlayOutPluginMessaging packet = new PacketPlayOutPluginMessaging(new NamespacedKey("bungeecord", "main"), out.toByteArray());
byte[] packetByte = packet.serializePacket(); byte[] packetByte = packet.serializePacket();
DataTypeIO.writeVarInt(output, packetByte.length); DataTypeIO.writeVarInt(output, packetByte.length);
output.write(packetByte); output.write(packetByte);
} }
public static InetAddress readIPResponse(byte[] data) throws UnknownHostException { public static InetAddress readIPResponse(byte[] data) throws UnknownHostException {
ByteArrayDataInput in = ByteStreams.newDataInput(data); ByteArrayDataInput in = ByteStreams.newDataInput(data);
String subchannel = in.readUTF(); String subchannel = in.readUTF();
if (subchannel.equals("IP")) { if (subchannel.equals("IP")) {
String ip = in.readUTF(); String ip = in.readUTF();
in.readInt(); in.readInt();
return InetAddress.getByName(ip); return InetAddress.getByName(ip);
} else { } else {
throw new RuntimeException("Bungeecord Message receieved is not an IP"); throw new RuntimeException("Bungeecord Message receieved is not an IP");
} }
} }
} }

View File

@ -4,23 +4,23 @@ import net.querz.mca.Section;
public class ChunkDataUtils { public class ChunkDataUtils {
public static void adjustBlockStateBits(int newBits, Section section, int dataVersion) { public static void adjustBlockStateBits(int newBits, Section section, int dataVersion) {
//increases or decreases the amount of bits used per BlockState //increases or decreases the amount of bits used per BlockState
//based on the size of the palette. //based on the size of the palette.
long[] blockStates = section.getBlockStates(); long[] blockStates = section.getBlockStates();
long[] newBlockStates; long[] newBlockStates;
if (dataVersion < 2527) { if (dataVersion < 2527) {
newBlockStates = newBits == blockStates.length / 64 ? blockStates : new long[newBits * 64]; newBlockStates = newBits == blockStates.length / 64 ? blockStates : new long[newBits * 64];
} else { } else {
int newLength = (int) Math.ceil(4096D / (64D / newBits)); int newLength = (int) Math.ceil(4096D / (64D / newBits));
newBlockStates = newBits == blockStates.length / 64 ? blockStates : new long[newLength]; newBlockStates = newBits == blockStates.length / 64 ? blockStates : new long[newLength];
} }
for (int i = 0; i < 4096; i++) { for (int i = 0; i < 4096; i++) {
section.setPaletteIndex(i, section.getPaletteIndex(i), newBlockStates); section.setPaletteIndex(i, section.getPaletteIndex(i), newBlockStates);
} }
section.setBlockStates(newBlockStates); section.setBlockStates(newBlockStates);
} }
} }

View File

@ -2,20 +2,20 @@ package com.loohp.limbo.utils;
public class CustomArrayUtils { public class CustomArrayUtils {
public static int[] longArrayToIntArray(long[] numbers) { public static int[] longArrayToIntArray(long[] numbers) {
int[] intNumbers = new int[numbers.length]; int[] intNumbers = new int[numbers.length];
for(int i = 0; i < numbers.length; i++) { for (int i = 0; i < numbers.length; i++) {
intNumbers[i] = (int) numbers[i]; intNumbers[i] = (int) numbers[i];
} }
return intNumbers; return intNumbers;
} }
public static byte[] longArrayToByteArray(long[] numbers) { public static byte[] longArrayToByteArray(long[] numbers) {
byte[] intNumbers = new byte[numbers.length]; byte[] intNumbers = new byte[numbers.length];
for(int i = 0; i < numbers.length; i++) { for (int i = 0; i < numbers.length; i++) {
intNumbers[i] = (byte) numbers[i]; intNumbers[i] = (byte) numbers[i];
} }
return intNumbers; return intNumbers;
} }
} }

View File

@ -1,180 +1,167 @@
package com.loohp.limbo.utils; package com.loohp.limbo.utils;
import net.querz.nbt.tag.*;
import org.json.simple.JSONArray; import org.json.simple.JSONArray;
import org.json.simple.JSONObject; 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") @SuppressWarnings("rawtypes")
public class CustomNBTUtils { public class CustomNBTUtils {
public enum TagClass { public static Class<? extends Tag> getClassFromName(String name) {
CompoundTagClass(CompoundTag.class), for (TagClass clazz : TagClass.values()) {
ByteTagClass(ByteTag.class), if (clazz.getTagClass().getSimpleName().equals(name)) {
ShortTagClass(ShortTag.class), return clazz.getTagClass();
IntTagClass(IntTag.class), }
LongTagClass(LongTag.class), }
FloatTagClass(FloatTag.class), return null;
DoubleTagClass(DoubleTag.class), }
ByteArrayTagClass(ByteArrayTag.class),
IntArrayTagClass(IntArrayTag.class),
LongArrayTagClass(LongArrayTag.class),
StringTagClass(StringTag.class),
ListTagClass(ListTag.class);
Class<? extends Tag> clazz; public static CompoundTag getCompoundTagFromJson(JSONObject json) {
CompoundTag tag = new CompoundTag();
TagClass(Class<? extends Tag> clazz) { for (Object obj : json.keySet()) {
this.clazz = clazz; String key = (String) obj;
} JSONObject inside = (JSONObject) json.get(key);
String type = (String) inside.get("type");
public Class<? extends Tag> getTagClass() { switch (type) {
return clazz; 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;
}
}
public static Class<? extends Tag> getClassFromName(String name) { return tag;
for (TagClass clazz : TagClass.values()) { }
if (clazz.getTagClass().getSimpleName().equals(name)) {
return clazz.getTagClass();
}
}
return null;
}
public static CompoundTag getCompoundTagFromJson(JSONObject json) { public static ListTag<?> getListTagFromJson(JSONObject json) {
CompoundTag tag = new CompoundTag(); String type = (String) json.get("type");
JSONArray array = (JSONArray) json.get("list");
for (Object obj : json.keySet()) { ListTag<?> listTag = ListTag.createUnchecked(getClassFromName(type));
String key = (String) obj;
JSONObject inside = (JSONObject) json.get(key);
String type = (String) inside.get("type");
switch (type) { switch (type) {
case "ByteTag": case "ByteTag":
tag.putByte(key, (byte) (long) inside.get("value")); for (Object obj : array) {
break; listTag.addByte((byte) (long) obj);
case "ShortTag": }
tag.putShort(key, (short) (long) inside.get("value")); break;
break; case "ShortTag":
case "IntTag": for (Object obj : array) {
tag.putInt(key, (int) (long) inside.get("value")); listTag.addShort((short) (long) obj);
break; }
case "LongTag": break;
tag.putLong(key, (long) inside.get("value")); case "IntTag":
break; for (Object obj : array) {
case "FloatTag": listTag.addInt((int) (long) obj);
tag.putFloat(key, inside.get("value") instanceof Long ? (float) (long) inside.get("value") : (float) (double) inside.get("value")); }
break; break;
case "DoubleTag": case "LongTag":
tag.putDouble(key, inside.get("value") instanceof Long ? (double) (long) inside.get("value") : (double) inside.get("value")); for (Object obj : array) {
break; listTag.addLong((long) obj);
case "ByteArrayTag": }
tag.putByteArray(key, CustomArrayUtils.longArrayToByteArray((long[]) inside.get("value"))); break;
break; case "FloatTag":
case "IntArrayTag": for (Object obj : array) {
tag.putIntArray(key, CustomArrayUtils.longArrayToIntArray((long[]) inside.get("value"))); listTag.addFloat(obj instanceof Long ? (float) (long) obj : (float) (double) obj);
break; }
case "LongArrayTag": break;
tag.putLongArray(key, (long[]) inside.get("value")); case "DoubleTag":
break; for (Object obj : array) {
case "StringTag": listTag.addDouble(obj instanceof Long ? (double) (long) obj : (double) obj);
tag.putString(key, (String) inside.get("value")); }
break; break;
case "CompoundTag": case "ByteArrayTag":
tag.put(key, getCompoundTagFromJson((JSONObject) inside.get("value"))); for (Object obj : array) {
break; listTag.addByteArray(CustomArrayUtils.longArrayToByteArray((long[]) obj));
case "ListTag": }
tag.put(key, getListTagFromJson((JSONObject) inside.get("value"))); break;
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 tag; return listTag;
} }
public static ListTag<?> getListTagFromJson(JSONObject json) { public enum TagClass {
String type = (String) json.get("type"); CompoundTagClass(CompoundTag.class),
JSONArray array = (JSONArray) json.get("list"); 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);
ListTag<?> listTag = ListTag.createUnchecked(getClassFromName(type)); Class<? extends Tag> clazz;
switch (type) { TagClass(Class<? extends Tag> clazz) {
case "ByteTag": this.clazz = clazz;
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 Class<? extends Tag> getTagClass() {
} return clazz;
}
}
} }

View File

@ -6,62 +6,62 @@ import java.util.List;
public class CustomStringUtils { public class CustomStringUtils {
public static boolean arrayContains(String compare, String[] args, boolean IgnoreCase) { 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)); 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) { public static boolean arrayContains(String compare, String[] args) {
return arrayContains(compare, args, true); return arrayContains(compare, args, true);
} }
public static String[] splitStringToArgs(String str) { public static String[] splitStringToArgs(String str) {
List<String> tokens = new ArrayList<String>(); List<String> tokens = new ArrayList<String>();
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
boolean insideQuote = false; boolean insideQuote = false;
for (char c : str.toCharArray()) { for (char c : str.toCharArray()) {
if (c == '"') { if (c == '"') {
insideQuote = !insideQuote; insideQuote = !insideQuote;
} else if (c == ' ' && !insideQuote) { } else if (c == ' ' && !insideQuote) {
if (sb.length() > 0) { if (sb.length() > 0) {
tokens.add(sb.toString()); tokens.add(sb.toString());
} }
sb.delete(0, sb.length()); sb.delete(0, sb.length());
} else { } else {
sb.append(c); sb.append(c);
} }
} }
tokens.add(sb.toString()); tokens.add(sb.toString());
return tokens.toArray(new String[tokens.size()]); return tokens.toArray(new String[tokens.size()]);
} }
public static int getIndexOfArg(String str, int ordinal) { public static int getIndexOfArg(String str, int ordinal) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
boolean insideQuote = false; boolean insideQuote = false;
int pos = 0; int pos = 0;
int found = 0; int found = 0;
for (char c : str.toCharArray()) { for (char c : str.toCharArray()) {
if (c == '"') { if (c == '"') {
insideQuote = !insideQuote; insideQuote = !insideQuote;
} else if (c == ' ' && !insideQuote) { } else if (c == ' ' && !insideQuote) {
if (sb.length() > 0) { if (sb.length() > 0) {
found++; found++;
} }
sb.delete(0, sb.length()); sb.delete(0, sb.length());
} else { } else {
sb.append(c); sb.append(c);
} }
if (found == ordinal) { if (found == ordinal) {
return pos; return pos;
} }
pos++; pos++;
} }
return -1; return -1;
} }
} }

View File

@ -1,5 +1,10 @@
package com.loohp.limbo.utils; 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.ByteArrayOutputStream;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
@ -7,129 +12,123 @@ import java.io.IOException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.UUID; 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 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)); out.writeLong(((position.getX() & 0x3FFFFFF) << 38) | ((position.getZ() & 0x3FFFFFF) << 12) | (position.getY() & 0xFFF));
} }
public static void writeUUID(DataOutputStream out, UUID uuid) throws IOException { public static void writeUUID(DataOutputStream out, UUID uuid) throws IOException {
out.writeLong(uuid.getMostSignificantBits()); out.writeLong(uuid.getMostSignificantBits());
out.writeLong(uuid.getLeastSignificantBits()); out.writeLong(uuid.getLeastSignificantBits());
} }
public static void writeCompoundTag(DataOutputStream out, CompoundTag tag) throws IOException { public static void writeCompoundTag(DataOutputStream out, CompoundTag tag) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer); DataOutputStream output = new DataOutputStream(buffer);
new NBTOutputStream(output).writeTag(tag, Tag.DEFAULT_MAX_DEPTH); new NBTOutputStream(output).writeTag(tag, Tag.DEFAULT_MAX_DEPTH);
byte[] b = buffer.toByteArray(); byte[] b = buffer.toByteArray();
out.write(b); out.write(b);
} }
public static String readString(DataInputStream in, Charset charset) throws IOException { public static String readString(DataInputStream in, Charset charset) throws IOException {
int length = readVarInt(in); int length = readVarInt(in);
if (length == -1) { if (length == -1) {
throw new IOException("Premature end of stream."); throw new IOException("Premature end of stream.");
} }
byte[] b = new byte[length]; byte[] b = new byte[length];
in.readFully(b); in.readFully(b);
return new String(b, charset); return new String(b, charset);
} }
public static int getStringLength(String string, Charset charset) throws IOException { public static int getStringLength(String string, Charset charset) throws IOException {
byte[] bytes = string.getBytes(charset); byte[] bytes = string.getBytes(charset);
return bytes.length; return bytes.length;
} }
public static void writeString(DataOutputStream out, String string, Charset charset) throws IOException { public static void writeString(DataOutputStream out, String string, Charset charset) throws IOException {
byte[] bytes = string.getBytes(charset); byte[] bytes = string.getBytes(charset);
writeVarInt(out, bytes.length); writeVarInt(out, bytes.length);
out.write(bytes); out.write(bytes);
} }
public static int readVarInt(DataInputStream in) throws IOException { public static int readVarInt(DataInputStream in) throws IOException {
int numRead = 0; int numRead = 0;
int result = 0; int result = 0;
byte read; byte read;
do { do {
read = in.readByte(); read = in.readByte();
int value = (read & 0b01111111); int value = (read & 0b01111111);
result |= (value << (7 * numRead)); result |= (value << (7 * numRead));
numRead++; numRead++;
if (numRead > 5) { if (numRead > 5) {
throw new RuntimeException("VarInt is too big"); throw new RuntimeException("VarInt is too big");
} }
} while ((read & 0b10000000) != 0); } while ((read & 0b10000000) != 0);
return result; return result;
} }
public static void writeVarInt(DataOutputStream out, int value) throws IOException { public static void writeVarInt(DataOutputStream out, int value) throws IOException {
do { do {
byte temp = (byte)(value & 0b01111111); byte temp = (byte) (value & 0b01111111);
// Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone // Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone
value >>>= 7; value >>>= 7;
if (value != 0) { if (value != 0) {
temp |= 0b10000000; temp |= 0b10000000;
} }
out.writeByte(temp); out.writeByte(temp);
} while (value != 0); } while (value != 0);
} }
public static int getVarIntLength(int value) throws IOException { public static int getVarIntLength(int value) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(buffer); DataOutputStream out = new DataOutputStream(buffer);
do { do {
byte temp = (byte)(value & 0b01111111); byte temp = (byte) (value & 0b01111111);
// Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone // Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone
value >>>= 7; value >>>= 7;
if (value != 0) { if (value != 0) {
temp |= 0b10000000; temp |= 0b10000000;
} }
out.writeByte(temp); out.writeByte(temp);
} while (value != 0); } while (value != 0);
return buffer.toByteArray().length; return buffer.toByteArray().length;
} }
public static long readVarLong(DataInputStream in) throws IOException { public static long readVarLong(DataInputStream in) throws IOException {
int numRead = 0; int numRead = 0;
long result = 0; long result = 0;
byte read; byte read;
do { do {
read = in.readByte(); read = in.readByte();
long value = (read & 0b01111111); long value = (read & 0b01111111);
result |= (value << (7 * numRead)); result |= (value << (7 * numRead));
numRead++; numRead++;
if (numRead > 10) { if (numRead > 10) {
throw new RuntimeException("VarLong is too big"); throw new RuntimeException("VarLong is too big");
} }
} while ((read & 0b10000000) != 0); } while ((read & 0b10000000) != 0);
return result; return result;
} }
public static void writeVarLong(DataOutputStream out, long value) throws IOException { public static void writeVarLong(DataOutputStream out, long value) throws IOException {
do { do {
byte temp = (byte)(value & 0b01111111); byte temp = (byte) (value & 0b01111111);
// Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone // Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone
value >>>= 7; value >>>= 7;
if (value != 0) { if (value != 0) {
temp |= 0b10000000; temp |= 0b10000000;
} }
out.writeByte(temp); out.writeByte(temp);
} while (value != 0); } while (value != 0);
} }
} }

View File

@ -1,56 +1,56 @@
package com.loohp.limbo.utils; 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.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.List; 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 class DeclareCommands {
public static PacketPlayOutDeclareCommands getDeclareCommandsPacket(CommandSender sender) throws IOException { public static PacketPlayOutDeclareCommands getDeclareCommandsPacket(CommandSender sender) throws IOException {
List<String> commands = Limbo.getInstance().getPluginManager().getTabOptions(sender, new String[0]); List<String> commands = Limbo.getInstance().getPluginManager().getTabOptions(sender, new String[0]);
if (commands.isEmpty()) { if (commands.isEmpty()) {
return null; return null;
} }
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer); DataOutputStream output = new DataOutputStream(buffer);
DataTypeIO.writeVarInt(output, commands.size() * 2 + 1); DataTypeIO.writeVarInt(output, commands.size() * 2 + 1);
output.writeByte(0); output.writeByte(0);
DataTypeIO.writeVarInt(output, commands.size()); DataTypeIO.writeVarInt(output, commands.size());
for (int i = 1; i <= commands.size() * 2; i++) { for (int i = 1; i <= commands.size() * 2; i++) {
DataTypeIO.writeVarInt(output, i++); DataTypeIO.writeVarInt(output, i++);
} }
int i = 1; int i = 1;
for (String label : commands) { for (String label : commands) {
output.writeByte(1 | 0x04); output.writeByte(1 | 0x04);
DataTypeIO.writeVarInt(output, 1); DataTypeIO.writeVarInt(output, 1);
DataTypeIO.writeVarInt(output, i + 1); DataTypeIO.writeVarInt(output, i + 1);
DataTypeIO.writeString(output, label, StandardCharsets.UTF_8); DataTypeIO.writeString(output, label, StandardCharsets.UTF_8);
i++; i++;
output.writeByte(2 | 0x04 | 0x10); output.writeByte(2 | 0x04 | 0x10);
DataTypeIO.writeVarInt(output, 1); DataTypeIO.writeVarInt(output, 1);
DataTypeIO.writeVarInt(output, i); DataTypeIO.writeVarInt(output, i);
DataTypeIO.writeString(output, "arg", StandardCharsets.UTF_8); DataTypeIO.writeString(output, "arg", StandardCharsets.UTF_8);
DataTypeIO.writeString(output, "brigadier:string", StandardCharsets.UTF_8); DataTypeIO.writeString(output, "brigadier:string", StandardCharsets.UTF_8);
DataTypeIO.writeVarInt(output, 0); DataTypeIO.writeVarInt(output, 0);
DataTypeIO.writeString(output, "minecraft:ask_server", StandardCharsets.UTF_8); DataTypeIO.writeString(output, "minecraft:ask_server", StandardCharsets.UTF_8);
i++; i++;
} }
DataTypeIO.writeVarInt(output, 0); DataTypeIO.writeVarInt(output, 0);
return new PacketPlayOutDeclareCommands(buffer.toByteArray()); return new PacketPlayOutDeclareCommands(buffer.toByteArray());
} }
} }

View File

@ -2,43 +2,43 @@ package com.loohp.limbo.utils;
public enum GameMode { public enum GameMode {
SURVIVAL(0, "survival"), SURVIVAL(0, "survival"),
CREATIVE(1, "creative"), CREATIVE(1, "creative"),
ADVENTURE(2, "adventure"), ADVENTURE(2, "adventure"),
SPECTATOR(3, "spectator"); SPECTATOR(3, "spectator");
int id; int id;
String name; String name;
GameMode(int id, String name) { GameMode(int id, String name) {
this.id = id; this.id = id;
this.name = name; this.name = name;
} }
public int getId() { public static GameMode fromId(int id) {
return id; for (GameMode mode : GameMode.values()) {
} if (mode.getId() == id) {
return mode;
}
}
return null;
}
public String getName() { public static GameMode fromName(String name) {
return name; for (GameMode mode : GameMode.values()) {
} if (mode.getName().equalsIgnoreCase(name)) {
return mode;
}
}
return null;
}
public static GameMode fromId(int id) { public int getId() {
for (GameMode mode : GameMode.values()) { return id;
if (mode.getId() == id) { }
return mode;
}
}
return null;
}
public static GameMode fromName(String name) { public String getName() {
for (GameMode mode : GameMode.values()) { return name;
if (mode.getName().equalsIgnoreCase(name)) { }
return mode;
}
}
return null;
}
} }

View File

@ -1,18 +1,17 @@
package com.loohp.limbo.utils; package com.loohp.limbo.utils;
import javax.imageio.ImageIO;
import java.awt.image.RenderedImage; import java.awt.image.RenderedImage;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.Base64; import java.util.Base64;
import javax.imageio.ImageIO;
public class ImageUtils { public class ImageUtils {
public static String imgToBase64String(final RenderedImage img, String formatName) throws IOException { public static String imgToBase64String(final RenderedImage img, String formatName) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
ImageIO.write(img, formatName, out); ImageIO.write(img, formatName, out);
return Base64.getEncoder().encodeToString(out.toByteArray()); return Base64.getEncoder().encodeToString(out.toByteArray());
} }
} }

View File

@ -1,5 +1,6 @@
package com.loohp.limbo.utils; package com.loohp.limbo.utils;
import javax.net.ssl.HttpsURLConnection;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
@ -7,87 +8,85 @@ import java.net.URL;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.net.ssl.HttpsURLConnection;
public class MojangAPIUtils { public class MojangAPIUtils {
public static class SkinResponse { public static UUID getOnlineUUIDOfPlayerFromMojang(String username) {
try {
String skin; URL url = new URL("https://api.mojang.com/users/profiles/minecraft/" + username);
String signature; HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
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();
connection.setUseCaches(false); connection.setUseCaches(false);
connection.setDefaultUseCaches(false); connection.setDefaultUseCaches(false);
connection.addRequestProperty("User-Agent", "Mozilla/5.0"); connection.addRequestProperty("User-Agent", "Mozilla/5.0");
connection.addRequestProperty("Cache-Control", "no-cache, no-store, must-revalidate"); connection.addRequestProperty("Cache-Control", "no-cache, no-store, must-revalidate");
connection.addRequestProperty("Pragma", "no-cache"); connection.addRequestProperty("Pragma", "no-cache");
if (connection.getResponseCode() == HttpsURLConnection.HTTP_OK) { if (connection.getResponseCode() == HttpsURLConnection.HTTP_OK) {
String reply = new BufferedReader(new InputStreamReader(connection.getInputStream())).readLine(); String reply = new BufferedReader(new InputStreamReader(connection.getInputStream())).readLine();
if (!reply.contains("\"error\":\"BadRequestException\"")) { if (!reply.contains("\"error\":\"BadRequestException\"")) {
String uuid = reply.split("\"id\":\"")[1].split("\"")[0]; 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")); 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 { } else {
return null; return null;
} }
} else { } else {
System.err.println("Connection could not be opened (Response code " + connection.getResponseCode() + ", " + connection.getResponseMessage() + ")"); System.err.println("Connection could not be opened (Response code " + connection.getResponseCode() + ", " + connection.getResponseMessage() + ")");
return null; return null;
} }
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
return null; return null;
} }
} }
public static SkinResponse getSkinFromMojangServer(String username) { public static SkinResponse getSkinFromMojangServer(String username) {
UUID uuid = getOnlineUUIDOfPlayerFromMojang(username); UUID uuid = getOnlineUUIDOfPlayerFromMojang(username);
if (uuid == null) { if (uuid == null) {
return null; return null;
} }
return getSkinFromMojangServer(uuid); return getSkinFromMojangServer(uuid);
} }
public static SkinResponse getSkinFromMojangServer(UUID uuid) { public static SkinResponse getSkinFromMojangServer(UUID uuid) {
try { try {
URL url = new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + uuid.toString() + "?unsigned=false"); URL url = new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + uuid.toString() + "?unsigned=false");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setUseCaches(false); connection.setUseCaches(false);
connection.setDefaultUseCaches(false); connection.setDefaultUseCaches(false);
connection.addRequestProperty("User-Agent", "Mozilla/5.0"); connection.addRequestProperty("User-Agent", "Mozilla/5.0");
connection.addRequestProperty("Cache-Control", "no-cache, no-store, must-revalidate"); connection.addRequestProperty("Cache-Control", "no-cache, no-store, must-revalidate");
connection.addRequestProperty("Pragma", "no-cache"); connection.addRequestProperty("Pragma", "no-cache");
if (connection.getResponseCode() == HttpsURLConnection.HTTP_OK) { if (connection.getResponseCode() == HttpsURLConnection.HTTP_OK) {
String reply = String.join("", new BufferedReader(new InputStreamReader(connection.getInputStream())).lines().collect(Collectors.toList())).replace(" ", ""); String reply = String.join("", new BufferedReader(new InputStreamReader(connection.getInputStream())).lines().collect(Collectors.toList())).replace(" ", "");
String skin = reply.split("\"value\":\"")[1].split("\"")[0]; String skin = reply.split("\"value\":\"")[1].split("\"")[0];
String signature = reply.split("\"signature\":\"")[1].split("\"")[0]; String signature = reply.split("\"signature\":\"")[1].split("\"")[0];
return new SkinResponse(skin, signature); return new SkinResponse(skin, signature);
} else { } else {
System.err.println("Connection could not be opened (Response code " + connection.getResponseCode() + ", " + connection.getResponseMessage() + ")"); System.err.println("Connection could not be opened (Response code " + connection.getResponseCode() + ", " + connection.getResponseMessage() + ")");
return null; return null;
} }
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
return null; 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;
}
}
} }

View File

@ -2,73 +2,70 @@ package com.loohp.limbo.utils;
public class NamespacedKey { public class NamespacedKey {
public static final String MINECRAFT_KEY = "minecraft"; public static final String MINECRAFT_KEY = "minecraft";
private String namespace; private final String namespace;
private String key; private final String key;
public NamespacedKey(String namespacedKey) { public NamespacedKey(String namespacedKey) {
int index = namespacedKey.indexOf(":"); int index = namespacedKey.indexOf(":");
if (index >= 0) { if (index >= 0) {
this.namespace = namespacedKey.substring(0, index); this.namespace = namespacedKey.substring(0, index);
this.key = namespacedKey.substring(index + 1); this.key = namespacedKey.substring(index + 1);
} else { } else {
this.namespace = "minecraft"; this.namespace = "minecraft";
this.key = namespacedKey; this.key = namespacedKey;
} }
} }
public NamespacedKey(String namespace, String key) { public NamespacedKey(String namespace, String key) {
this.namespace = namespace; this.namespace = namespace;
this.key = key; this.key = key;
} }
public static NamespacedKey minecraft(String key) { public static NamespacedKey minecraft(String key) {
return new NamespacedKey(MINECRAFT_KEY, key); return new NamespacedKey(MINECRAFT_KEY, key);
} }
public String getNamespace() { public String getNamespace() {
return namespace; return namespace;
} }
public String getKey() { public String getKey() {
return key; return key;
} }
@Override @Override
public String toString() { public String toString() {
return namespace + ":" + key; return namespace + ":" + key;
} }
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
int result = 1; int result = 1;
result = prime * result + ((key == null) ? 0 : key.hashCode()); result = prime * result + ((key == null) ? 0 : key.hashCode());
result = prime * result + ((namespace == null) ? 0 : namespace.hashCode()); result = prime * result + ((namespace == null) ? 0 : namespace.hashCode());
return result; return result;
} }
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) if (this == obj)
return true; return true;
if (obj == null) if (obj == null)
return false; return false;
if (getClass() != obj.getClass()) if (getClass() != obj.getClass())
return false; return false;
NamespacedKey other = (NamespacedKey) obj; NamespacedKey other = (NamespacedKey) obj;
if (key == null) { if (key == null) {
if (other.key != null) if (other.key != null)
return false; return false;
} else if (!key.equals(other.key)) } else if (!key.equals(other.key))
return false; return false;
if (namespace == null) { if (namespace == null) {
if (other.namespace != null) return other.namespace == null;
return false; } else return namespace.equals(other.namespace);
} else if (!namespace.equals(other.namespace)) }
return false;
return true;
}
} }

View File

@ -6,31 +6,31 @@ import java.net.ServerSocket;
public class NetworkUtils { public class NetworkUtils {
public static boolean available(int port) { public static boolean available(int port) {
ServerSocket ss = null; ServerSocket ss = null;
DatagramSocket ds = null; DatagramSocket ds = null;
try { try {
ss = new ServerSocket(port); ss = new ServerSocket(port);
ss.setReuseAddress(true); ss.setReuseAddress(true);
ds = new DatagramSocket(port); ds = new DatagramSocket(port);
ds.setReuseAddress(true); ds.setReuseAddress(true);
return true; return true;
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} finally { } finally {
if (ds != null) { if (ds != null) {
ds.close(); ds.close();
} }
if (ss != null) { if (ss != null) {
try { try {
ss.close(); ss.close();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
return false; return false;
} }
} }

Some files were not shown because too many files have changed in this diff Show More