-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d85222b
commit e93a601
Showing
65 changed files
with
1,204 additions
and
565 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
// Declare dependencies | ||
dependencies {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Mod | ||
mod_name = Essential Commands Core | ||
mod_id = ec-core | ||
mod_version = 1.0.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package dev.jpcode.eccore; | ||
|
||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
|
||
public class ECCore { | ||
public static final Logger LOGGER = LogManager.getLogger("ec-core"); | ||
|
||
} |
152 changes: 152 additions & 0 deletions
152
ec-core/src/main/java/dev/jpcode/eccore/config/Config.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
package dev.jpcode.eccore.config; | ||
|
||
import net.minecraft.text.LiteralText; | ||
import net.minecraft.text.MutableText; | ||
import net.minecraft.text.Style; | ||
import net.minecraft.text.Text; | ||
import net.minecraft.util.Formatting; | ||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
import java.io.File; | ||
import java.io.FileReader; | ||
import java.io.FileWriter; | ||
import java.io.IOException; | ||
import java.lang.reflect.Field; | ||
import java.lang.reflect.Modifier; | ||
import java.nio.file.Path; | ||
import java.util.Arrays; | ||
import java.util.Comparator; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
public abstract class Config { | ||
static final Logger LOGGER = LogManager.getLogger("ec-core-config"); | ||
|
||
protected SortedProperties props; | ||
private final Path configPath; | ||
private final String displayName; | ||
private final String documentationLink; | ||
|
||
public Config(Path savePath, String displayName, String documentationLink) { | ||
this.configPath = savePath; | ||
this.displayName = displayName; | ||
this.documentationLink = documentationLink; | ||
initFieldStorage(); | ||
} | ||
|
||
public void loadOrCreateProperties() { | ||
props = new SortedProperties(); | ||
File inFile = configPath.toFile(); | ||
|
||
try { | ||
boolean fileAlreadyExisted = !inFile.createNewFile(); | ||
if (fileAlreadyExisted) { | ||
props.load(new FileReader(inFile)); | ||
} | ||
} catch (IOException e) { | ||
LOGGER.warn("Failed to load preferences."); | ||
} | ||
initProperties(); | ||
storeProperties(); | ||
} | ||
|
||
private void initProperties() { | ||
Class<? extends Config> cls = this.getClass(); | ||
// Cursed reflection reloading of all properties. | ||
Arrays.stream(cls.getDeclaredFields()) | ||
.filter(field -> field.isAnnotationPresent(ConfigOption.class)) | ||
.forEach(field -> { | ||
try { | ||
((Option<?>) field.get(this)).loadAndSave(props); | ||
} catch (IllegalAccessException e) { | ||
e.printStackTrace(); | ||
} | ||
}); | ||
} | ||
|
||
public void storeProperties() { | ||
try { | ||
File outFile = configPath.toFile(); | ||
FileWriter writer = new FileWriter(outFile); | ||
|
||
props.storeSorted(writer, new StringBuilder(80) | ||
.append(displayName) | ||
.append("\n") | ||
.append("Config Documentation: ") | ||
.append(documentationLink) | ||
.toString() | ||
); | ||
} catch (IOException e) { | ||
LOGGER.warn("Failed to store preferences to disk."); | ||
} | ||
|
||
} | ||
|
||
static final Style DEFAULT_STYLE = Style.EMPTY.withFormatting(Formatting.GOLD); | ||
static final Style ACCENT_STYLE = Style.EMPTY.withFormatting(Formatting.GREEN); | ||
|
||
public @NotNull Text stateAsText() { | ||
LiteralText result = new LiteralText(""); | ||
String newLine = "\n";//System.getProperty("line.separator"); | ||
|
||
result.append(new LiteralText(displayName + " {").setStyle(DEFAULT_STYLE)); | ||
result.append(newLine); | ||
LiteralText propsText = new LiteralText(""); | ||
result.append(propsText); | ||
|
||
//print field names paired with their values | ||
for (Field field : publicFields) { | ||
try { | ||
if (Modifier.isPublic(field.getModifiers())) { | ||
propsText.append(fieldAsText(field).append(newLine)); | ||
} | ||
} catch (IllegalAccessException ex) { | ||
ex.printStackTrace(); | ||
} | ||
} | ||
result.append(new LiteralText("}").setStyle(ACCENT_STYLE)); | ||
|
||
return result; | ||
|
||
} | ||
|
||
private List<String> publicFieldNames; | ||
private List<Field> publicFields; | ||
|
||
private void initFieldStorage() { | ||
Class<? extends Config> cls = this.getClass(); | ||
publicFieldNames = Arrays.stream(cls.getDeclaredFields()) | ||
.filter(field -> Modifier.isPublic(field.getModifiers())) | ||
.map(Field::getName) | ||
.sorted() | ||
.collect(Collectors.toList()); | ||
publicFields = Arrays.stream(cls.getDeclaredFields()) | ||
.filter(field -> Modifier.isPublic(field.getModifiers())) | ||
.sorted(Comparator.comparing(Field::getName)) | ||
.collect(Collectors.toList()); | ||
|
||
} | ||
|
||
public List<String> getPublicFieldNames() { | ||
return publicFieldNames; | ||
} | ||
|
||
private MutableText fieldAsText(Field field) throws IllegalAccessException { | ||
return new LiteralText("") | ||
.append(new LiteralText(field.getName() + ": ").setStyle(DEFAULT_STYLE)) | ||
.append(new LiteralText(field.get(this.getClass()).toString())); | ||
} | ||
|
||
public @Nullable MutableText getFieldValueAsText(String fieldName) throws NoSuchFieldException { | ||
try { | ||
return fieldAsText(this.getClass().getField(fieldName)); | ||
} catch (IllegalAccessException e) { | ||
e.printStackTrace(); | ||
} | ||
return null; | ||
} | ||
|
||
} |
11 changes: 11 additions & 0 deletions
11
ec-core/src/main/java/dev/jpcode/eccore/config/ConfigOption.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package dev.jpcode.eccore.config; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target(ElementType.FIELD) | ||
public @interface ConfigOption { | ||
} |
137 changes: 137 additions & 0 deletions
137
ec-core/src/main/java/dev/jpcode/eccore/config/ConfigUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
package dev.jpcode.eccore.config; | ||
|
||
import com.google.gson.JsonParser; | ||
import com.google.gson.JsonSyntaxException; | ||
import net.minecraft.text.Style; | ||
import net.minecraft.text.Text; | ||
import net.minecraft.util.Formatting; | ||
import org.apache.logging.log4j.Level; | ||
import org.jetbrains.annotations.Contract; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
import static dev.jpcode.eccore.config.Config.LOGGER; | ||
import static dev.jpcode.eccore.util.TextUtil.parseText; | ||
|
||
/** | ||
* Various parsers, etc. | ||
*/ | ||
public final class ConfigUtil { | ||
|
||
private ConfigUtil() {} | ||
|
||
// TODO do not delclair serializer objects out here. Pretty sure is bad for concurrent parsing. | ||
private static final Style.Serializer styleJsonDeserializer = new Style.Serializer(); | ||
private static final JsonParser jsonParser = new JsonParser(); | ||
|
||
public static Style parseStyleOrDefault(String styleStr, String defaultStyleStr) { | ||
Style outStyle = null; | ||
if (styleStr != null) { | ||
outStyle = parseStyle(styleStr); | ||
} | ||
|
||
if (outStyle == null) { | ||
outStyle = parseStyle(defaultStyleStr); | ||
LOGGER.log( | ||
Level.WARN, | ||
String.format("Could not load malformed style: '%s'. Using default, '%s'.", styleStr, defaultStyleStr) | ||
); | ||
} | ||
return outStyle; | ||
} | ||
|
||
public static Style parseStyle(String styleStr) { | ||
Style outStyle = null; | ||
Formatting formatting = Formatting.byName(styleStr); | ||
if (formatting != null) { | ||
outStyle = Style.EMPTY.withFormatting(formatting); | ||
} | ||
|
||
if (outStyle == null) { | ||
try { | ||
outStyle = styleJsonDeserializer.deserialize( | ||
jsonParser.parse(styleStr), | ||
null, null | ||
); | ||
} catch (JsonSyntaxException e) { | ||
LOGGER.log(Level.ERROR, String.format( | ||
"Malformed Style JSON in config: %s", styleStr | ||
)); | ||
// e.printStackTrace(); | ||
} | ||
|
||
} | ||
|
||
return outStyle; | ||
} | ||
|
||
public static Text parseTextOrDefault(String textStr, String defaultTextStr) { | ||
Text outText = null; | ||
if (textStr != null) { | ||
outText = parseText(textStr); | ||
} | ||
|
||
if (outText == null) { | ||
outText = parseText(defaultTextStr); | ||
LOGGER.log( | ||
Level.WARN, | ||
String.format("Could not load malformed Text: '%s'. Using default, '%s'.", textStr, defaultTextStr) | ||
); | ||
} | ||
return outText; | ||
} | ||
|
||
public static int parseInt(String s) { | ||
try { | ||
return Integer.parseInt(s); | ||
} catch (NumberFormatException e) { | ||
logNumberParseError(s, "int"); | ||
} | ||
return -1; | ||
} | ||
|
||
public static double parseDouble(String s) { | ||
try { | ||
return Double.parseDouble(s); | ||
} catch (NumberFormatException e) { | ||
logNumberParseError(s, "double"); | ||
} | ||
return -1; | ||
} | ||
|
||
@Contract(pure = true) | ||
public static <T> @NotNull ValueParser<List<T>> csvParser(ValueParser<T> valueParser) { | ||
return (String value) -> parseCsv(value, valueParser); | ||
} | ||
|
||
public static <T> List<T> parseCsv(@NotNull String csvString, @NotNull ValueParser<T> valueParser) { | ||
return Arrays.stream(csvString.split(",")).sequential().map(String::trim) | ||
.map(valueParser::parseValue).collect(Collectors.toList()); | ||
} | ||
|
||
@Contract(pure = true) | ||
public static <T> @NotNull ValueParser<List<T>> arrayParser(ValueParser<T> valueParser) { | ||
return (String value) -> parseArray(value, valueParser); | ||
} | ||
|
||
public static <T> List<T> parseArray(@NotNull String arrayString, @NotNull ValueParser<T> valueParser) { | ||
int endIdx = arrayString.indexOf(']'); | ||
return parseCsv( | ||
arrayString.substring(arrayString.indexOf('[') + 1, endIdx == -1 ? arrayString.length() : endIdx), | ||
valueParser | ||
); | ||
} | ||
|
||
private static void logNumberParseError(String num, String type) { | ||
Config.LOGGER.log(Level.WARN, String.format( | ||
"Invalid number format for type '%s' in config. Value provided: '%s'", type, num | ||
)); | ||
} | ||
|
||
public static String serializeStyle(Style style) { | ||
return String.valueOf(styleJsonDeserializer.serialize(style, null, null)); | ||
} | ||
} |
Oops, something went wrong.