Javadoc a bit of Geyser (#392)

* A bunch of javadoc comments

* Cleaned up javadocs
This commit is contained in:
rtm516 2020-04-21 06:28:44 +01:00 committed by GitHub
parent 4ee95f585d
commit 1b15f3058f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 280 additions and 12 deletions

View File

@ -14,6 +14,13 @@ public enum AuthType {
return id < VALUES.length ? VALUES[id] : OFFLINE;
}
/**
* Convert the AuthType string (from config) to the enum, OFFLINE on fail
*
* @param name AuthType string
*
* @return The converted AuthType
*/
public static AuthType getByName(String name) {
String upperCase = name.toUpperCase();
for (AuthType type : VALUES) {

View File

@ -51,6 +51,13 @@ public class ChatColor {
public static final String ITALIC = ESCAPE + "o";
public static final String RESET = ESCAPE + "r";
/**
* Convert chat colour codes to terminal colours
*
* @param string The text to replace colours for
*
* @return A string ready for terminal printing
*/
public static String toANSI(String string) {
string = string.replace(BOLD, (char) 0x1b + "[1m");
string = string.replace(OBFUSCATED, (char) 0x1b + "[5m");
@ -81,6 +88,13 @@ public class ChatColor {
return message.replace(color, ESCAPE);
}
/**
* Remove all colour formatting tags from a message
*
* @param message Message to remove colour tags from
*
* @return The sanitised message
*/
public static String stripColors(String message) {
return message = message.replaceAll("(&([a-fk-or0-9]))","").replaceAll("(§([a-fk-or0-9]))","").replaceAll("s/\\x1b\\[[0-9;]*[a-zA-Z]//g","");
}

View File

@ -31,13 +31,34 @@ import org.geysermc.common.logger.IGeyserLogger;
public interface IGeyserBootstrap {
/**
* Called when the GeyserBootstrap is enabled
*/
void onEnable();
/**
* Called when the GeyserBootstrap is disabled
*/
void onDisable();
/**
* Returns the current GeyserConfig
*
* @return The current GeyserConfig
*/
IGeyserConfiguration getGeyserConfig();
/**
* Returns the current GeyserLogger
*
* @return The current GeyserLogger
*/
IGeyserLogger getGeyserLogger();
/**
* Returns the current GeyserCommandManager
*
* @return The current GeyserCommandManager
*/
ICommandManager getGeyserCommandManager();
}

View File

@ -27,5 +27,12 @@ package org.geysermc.common.command;
public interface ICommandManager {
/**
* Returns the description of the given command
*
* @param command Command to get the description for
*
* @return Command description
*/
String getDescription(String command);
}

View File

@ -44,8 +44,8 @@ public class TropicalFishEntity extends AbstractFishEntity {
@Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 16) {
// Still not always the right model and colour is broken
TropicalFishVariant variant = TropicalFishVariant.fromVariantNumber((int) entityMetadata.getValue());
metadata.put(EntityData.VARIANT, variant.getShape()); // Shape 0-1
metadata.put(EntityData.MARK_VARIANT, variant.getPattern()); // Pattern 0-5
metadata.put(EntityData.COLOR, variant.getBaseColor()); // Base color 0-15
@ -80,6 +80,13 @@ public class TropicalFishEntity extends AbstractFishEntity {
private byte baseColor;
private byte patternColor;
/**
* Convert the variant number from Java into separate values
*
* @param varNumber Variant number from Java edition
*
* @return The variant converted into TropicalFishVariant
*/
public static TropicalFishVariant fromVariantNumber(int varNumber) {
return new TropicalFishVariant((varNumber & 0xFF), ((varNumber >> 8) & 0xFF), (byte) ((varNumber >> 16) & 0xFF), (byte) ((varNumber >> 24) & 0xFF));
}

View File

@ -55,7 +55,7 @@ public class JavaServerDeclareCommandsTranslator extends PacketTranslator<Server
for (int nodeIndex : rootNode.getChildIndices()) {
CommandNode node = packet.getNodes()[nodeIndex];
// Make sure we dont have duplicated commands (happens if there is more than 1 root node)
// Make sure we don't have duplicated commands (happens if there is more than 1 root node)
if (commands.containsKey(nodeIndex)) { continue; }
// Get and update the commandArgs list with the found arguments
@ -81,7 +81,7 @@ public class JavaServerDeclareCommandsTranslator extends PacketTranslator<Server
CommandEnumData aliases = new CommandEnumData( commandName + "Aliases", new String[] { commandName.toLowerCase() }, false);
// Get and parse all params
CommandParamData[][] params = getParams(commandID, packet.getNodes()[commandID], packet.getNodes());
CommandParamData[][] params = getParams(packet.getNodes()[commandID], packet.getNodes());
// Build the completed command and add it to the final list
CommandData data = new CommandData(commandName, session.getConnector().getCommandManager().getDescription(commandName), flags, (byte) 0, aliases, params);
@ -100,7 +100,15 @@ public class JavaServerDeclareCommandsTranslator extends PacketTranslator<Server
session.getUpstream().sendPacket(availableCommandsPacket);
}
private CommandParamData[][] getParams(int commandID, CommandNode commandNode, CommandNode[] allNodes) {
/**
* Build the command parameter array for the given command
*
* @param commandNode The command to build the parameters for
* @param allNodes Every command node
*
* @return An array of parameter option arrays
*/
private CommandParamData[][] getParams(CommandNode commandNode, CommandNode[] allNodes) {
// Check if the command is an alias and redirect it
if (commandNode.getRedirectIndex() != -1) {
GeyserConnector.getInstance().getLogger().debug("Redirecting command " + commandNode.getName() + " to " + allNodes[commandNode.getRedirectIndex()].getName());
@ -128,6 +136,13 @@ public class JavaServerDeclareCommandsTranslator extends PacketTranslator<Server
return new CommandParamData[0][0];
}
/**
* Convert Java edition command types to Bedrock edition
*
* @param parser Command type to convert
*
* @return Bedrock parameter data type
*/
private CommandParamData.Type mapCommandType(CommandParser parser) {
if (parser == null) { return CommandParamData.Type.STRING; }
@ -204,12 +219,23 @@ public class JavaServerDeclareCommandsTranslator extends PacketTranslator<Server
private CommandParamData paramData;
private List<ParamInfo> children;
/**
* Create a new parameter info object
*
* @param paramNode CommandNode the parameter is for
* @param paramData The existing parameters for the command
*/
public ParamInfo(CommandNode paramNode, CommandParamData paramData) {
this.paramNode = paramNode;
this.paramData = paramData;
this.children = new ArrayList<>();
}
/**
* Build the array of all the child parameters (recursive)
*
* @param allNodes Every command node
*/
public void buildChildren(CommandNode[] allNodes) {
int enumIndex = -1;
@ -247,6 +273,11 @@ public class JavaServerDeclareCommandsTranslator extends PacketTranslator<Server
}
}
/**
* Get the tree of every parameter node (recursive)
*
* @return List of parameter options arrays for the command
*/
public List<CommandParamData[]> getTree() {
List<CommandParamData[]> treeParamData = new ArrayList<>();

View File

@ -61,6 +61,12 @@ public class DimensionUtils {
session.getUpstream().sendPacket(stopSoundPacket);
}
/**
* Map the Java edition dimension IDs to Bedrock edition
*
* @param javaDimension Dimension ID to convert
* @return Converted Bedrock edition dimension ID
*/
public static int javaToBedrock(int javaDimension) {
switch (javaDimension) {
case -1:

View File

@ -32,6 +32,12 @@ import org.geysermc.connector.entity.type.EntityType;
public class EntityUtils {
/**
* Convert Java edition effect IDs to Bedrock edition
*
* @param effect Effect to convert
* @return The numeric ID for the Bedrock edition effect
*/
public static int toBedrockEffectId(Effect effect) {
switch (effect) {
case GLOWING:
@ -51,6 +57,13 @@ public class EntityUtils {
return effect.ordinal() + 1;
}
}
/**
* Converts a MobType to a Bedrock edition EntityType, returns null if the EntityType is not found
*
* @param type The MobType to convert
* @return Converted EntityType
*/
public static EntityType toBedrockEntity(MobType type) {
try {
return EntityType.valueOf(type.name());
@ -59,6 +72,12 @@ public class EntityUtils {
}
}
/**
* Converts a ObjectType to a Bedrock edition EntityType, returns null if the EntityType is not found
*
* @param type The ObjectType to convert
* @return Converted EntityType
*/
public static EntityType toBedrockEntity(ObjectType type) {
try {
return EntityType.valueOf(type.name());

View File

@ -27,24 +27,51 @@ package org.geysermc.connector.utils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import org.geysermc.connector.GeyserConnector;
import java.io.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.function.Function;
public class FileUtils {
/**
* Load the given YAML file into the given class
*
* @param src File to load
* @param valueType Class to load file into
* @return The data as the given class
* @throws IOException
*/
public static <T> T loadConfig(File src, Class<T> valueType) throws IOException {
ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());
return objectMapper.readValue(src, valueType);
}
public static File fileOrCopiedFromResource(String name, Function<String, String> s) throws IOException {
return fileOrCopiedFromResource(new File(name), name, s);
/**
* Open the specified file or copy if from resources
*
* @param name File and resource name
* @param fallback Formatting callback
* @return File handle of the specified file
* @throws IOException
*/
public static File fileOrCopiedFromResource(String name, Function<String, String> fallback) throws IOException {
return fileOrCopiedFromResource(new File(name), name, fallback);
}
public static File fileOrCopiedFromResource(File file, String name, Function<String, String> s) throws IOException {
/**
* Open the specified file or copy if from resources
*
* @param file File to open
* @param name Name of the resource get if needed
* @param format Formatting callback
* @return File handle of the specified file
* @throws IOException
*/
public static File fileOrCopiedFromResource(File file, String name, Function<String, String> format) throws IOException {
if (!file.exists()) {
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
@ -54,7 +81,7 @@ public class FileUtils {
input.read(bytes);
for(char c : s.apply(new String(bytes)).toCharArray()) {
for(char c : format.apply(new String(bytes)).toCharArray()) {
fos.write(c);
}
@ -66,6 +93,13 @@ public class FileUtils {
return file;
}
/**
* Writes the given data to the specified file on disk
*
* @param file File to write to
* @param data Data to write to the file
* @throws IOException
*/
public static void writeFile(File file, char[] data) throws IOException {
if (!file.exists()) {
file.createNewFile();
@ -81,6 +115,13 @@ public class FileUtils {
fos.close();
}
/**
* Writes the given data to the specified file on disk
*
* @param name File path to write to
* @param data Data to write to the file
* @throws IOException
*/
public static void writeFile(String name, char[] data) throws IOException {
writeFile(new File(name), data);
}

View File

@ -57,9 +57,15 @@ public class LocaleUtils {
downloadAndLoadLocale(DEFAULT_LOCALE);
}
/**
* Fetch the latest versions asset cache from Mojang so we can grab the locale files later
*/
private static void generateAssetCache() {
try {
// Get the version manifest from Mojang
VersionManifest versionManifest = Toolbox.JSON_MAPPER.readValue(WebUtils.getBody("https://launchermeta.mojang.com/mc/game/version_manifest.json"), VersionManifest.class);
// Get the url for the latest version of the games manifest
String latestInfoURL = "";
for (Version version : versionManifest.getVersions()) {
if (version.getId().equals(versionManifest.getLatestVersion().getRelease())) {
@ -68,12 +74,15 @@ public class LocaleUtils {
}
}
// Make sure we definitely got a version
if (latestInfoURL.isEmpty()) {
throw new Exception("Unable to get latest Minecraft version");
}
// Get the individual version manifest
VersionInfo versionInfo = Toolbox.JSON_MAPPER.readValue(WebUtils.getBody(latestInfoURL), VersionInfo.class);
// Get the smallest jar for use when downloading the en_us locale, will be either the server or client
int currentSize = Integer.MAX_VALUE;
for (VersionDownload download : versionInfo.getDownloads().values()) {
if (download.getUrl().endsWith(".jar") && download.getSize() < currentSize) {
@ -82,8 +91,10 @@ public class LocaleUtils {
}
}
// Get the assets list
JsonNode assets = Toolbox.JSON_MAPPER.readTree(WebUtils.getBody(versionInfo.getAssetIndex().getUrl())).get("objects");
// Put each asset into an array for use later
Iterator<Map.Entry<String, JsonNode>> assetIterator = assets.fields();
while (assetIterator.hasNext()) {
Map.Entry<String, JsonNode> entry = assetIterator.next();
@ -95,8 +106,15 @@ public class LocaleUtils {
}
}
/**
* Downloads a locale from Mojang if its not already loaded
*
* @param locale Locale to download and load
*/
public static void downloadAndLoadLocale(String locale) {
locale = locale.toLowerCase();
// Check the locale isn't already loaded
if (!ASSET_MAP.containsKey("minecraft/lang/" + locale + ".json") && !locale.equals("en_us")) {
GeyserConnector.getInstance().getLogger().warning("Invalid locale requested to download and load: " + locale);
return;
@ -108,9 +126,15 @@ public class LocaleUtils {
loadLocale(locale);
}
/**
* Downloads the specified locale if its not already downloaded
*
* @param locale Locale to download
*/
private static void downloadLocale(String locale) {
File localeFile = new File("locales/" + locale + ".json");
// Check if we have already downloaded the locale file
if (localeFile.exists()) {
GeyserConnector.getInstance().getLogger().debug("Locale already downloaded: " + locale);
return;
@ -128,6 +152,11 @@ public class LocaleUtils {
WebUtils.downloadFile("http://resources.download.minecraft.net/" + hash.substring(0, 2) + "/" + hash, "locales/" + locale + ".json");
}
/**
* Loads a locale already downloaded, if the file doesn't exist it just logs a warning
*
* @param locale Locale to load
*/
private static void loadLocale(String locale) {
File localeFile = new File("locales/" + locale + ".json");
@ -146,7 +175,7 @@ public class LocaleUtils {
try {
localeObj = Toolbox.JSON_MAPPER.readTree(localeStream);
} catch (Exception e) {
throw new AssertionError("Unable to load Java lang map for " + locale, e);
throw new AssertionError("Unable to load Java edition lang map for " + locale, e);
}
// Parse all the locale fields
@ -164,6 +193,11 @@ public class LocaleUtils {
}
}
/**
* Download then en_us locale by downloading the server jar and extracting it from there.
*
* @param localeFile File to save the locale to
*/
private static void downloadEN_US(File localeFile) {
try {
// Let the user know we are downloading the JAR
@ -199,6 +233,13 @@ public class LocaleUtils {
}
}
/**
* Translate the given language string into the given locale, or falls back to the default locale
*
* @param messageText Language string to translate
* @param locale Locale to translate to
* @return Translated string or the original message if it was not found in the given locale
*/
public static String getLocaleString(String messageText, String locale) {
Map<String, String> localeStrings = LocaleUtils.LOCALE_MAPPINGS.get(locale.toLowerCase());
if (localeStrings == null)

View File

@ -27,6 +27,12 @@ package org.geysermc.connector.utils;
public class MathUtils {
/**
* Round the given float to the next whole number
*
* @param floatNumber Float to round
* @return Rounded number
*/
public static int ceil(float floatNumber) {
int truncated = (int) floatNumber;
return floatNumber > truncated ? truncated + 1 : truncated;

View File

@ -121,6 +121,13 @@ public class MessageUtils {
return getTranslatedBedrockMessage(message, null, false);
}
/**
* Inserts the given parameters into the given message both in sequence and as requested
*
* @param message Message containing possible parameter replacement strings
* @param params A list of parameter strings
* @return Parsed message with all params inserted as needed
*/
public static String insertParams(String message, List<String> params) {
String newMessage = message;
@ -130,7 +137,7 @@ public class MessageUtils {
try {
newMessage = newMessage.replaceFirst("%" + m.group(1) + "\\$s" , params.get(Integer.parseInt(m.group(1)) - 1));
} catch (Exception e) {
// Couldnt find the param to replace
// Couldn't find the param to replace
}
}
@ -141,6 +148,12 @@ public class MessageUtils {
return newMessage;
}
/**
* Gets the colour for the message style or fetches it from the parent (recursive)
*
* @param style The style to get the colour from
* @return Colour string to be used
*/
private static String getColorOrParent(MessageStyle style) {
ChatColor chatColor = style.getColor();
@ -151,6 +164,12 @@ public class MessageUtils {
return getColor(chatColor);
}
/**
* Convert a ChatColor into a string for inserting into messages
*
* @param color ChatColor to convert
* @return The converted color string
*/
private static String getColor(ChatColor color) {
String base = "\u00a7";
switch (color) {
@ -213,6 +232,12 @@ public class MessageUtils {
return base;
}
/**
* Convert a list of ChatFormats into a string for inserting into messages
*
* @param formats ChatFormats to convert
* @return The converted chat formatting string
*/
private static String getFormat(List<ChatFormat> formats) {
StringBuilder str = new StringBuilder();
for (ChatFormat cf : formats) {
@ -243,6 +268,12 @@ public class MessageUtils {
return str.toString();
}
/**
* Checks if the given text string is a json message
*
* @param text String to test
* @return True if its a valid message json string, false if not
*/
public static boolean isMessage(String text) {
JsonParser parser = new JsonParser();
try {
@ -296,6 +327,13 @@ public class MessageUtils {
return "";
}
/**
* Checks if the given message is over 256 characters (Java edition server chat limit) and sends a message to the user if it is
*
* @param message Message to check
* @param session GeyserSession for the user
* @return True if the message is too long, false if not
*/
public static boolean isTooLong(String message, GeyserSession session) {
if (message.length() > 256) {
// TODO: Add Geyser localization and translate this based on language

View File

@ -105,6 +105,12 @@ public class SkinUtils {
private String capeUrl;
private boolean alex;
/**
* Generate the GameProfileData from the given GameProfile
*
* @param profile GameProfile to build the GameProfileData from
* @return The built GameProfileData
*/
public static GameProfileData from(GameProfile profile) {
try {
GameProfile.Property skinProperty = profile.getProperty("textures");
@ -189,6 +195,12 @@ public class SkinUtils {
});
}
/**
* Create a basic geometry json for the given name
*
* @param geometryName Geometry name to use
* @return Geometry data as a json string
*/
private static String getLegacySkinGeometry(String geometryName) {
return "{\"geometry\" :{\"default\" :\"" + geometryName + "\"}}";
}

View File

@ -110,6 +110,12 @@ public class Toolbox {
LocaleUtils.init();
}
/**
* Get an InputStream for the given resource path, throws AssertionError if resource is not found
*
* @param resource Resource to get
* @return InputStream of the given resource
*/
public static InputStream getResource(String resource) {
InputStream stream = Toolbox.class.getClassLoader().getResourceAsStream(resource);
if (stream == null) {

View File

@ -36,6 +36,12 @@ import java.nio.file.StandardCopyOption;
public class WebUtils {
/**
* Makes a web request to the given URL and returns the body as a string
*
* @param reqURL URL to fetch
* @return Body contents or error message if the request fails
*/
public static String getBody(String reqURL) {
URL url = null;
try {
@ -61,6 +67,12 @@ public class WebUtils {
}
}
/**
* Downloads a file from the given URL and saves it to disk
*
* @param reqURL File to fetch
* @param fileLocation Location to save on disk
*/
public static void downloadFile(String reqURL, String fileLocation) {
try {
InputStream in = new URL(reqURL).openStream();