Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions src/main/java/nl/devpieter/utilize/Utilize.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ public void onInitializeClient() {

if (!ClientUtils.isDevEnv()) return;
LOGGER.info("Utilize is running in a development environment.");

// Sees sees = Sees.getInstance();
// sees.subscribe(new EventListeners());
}

public static boolean shouldBlockSwingHandOnce() {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import nl.devpieter.utilize.managers.SleepManager;
import nl.devpieter.utilize.managers.TaskManager;
import nl.devpieter.utilize.managers.TotemManager;
import nl.devpieter.utilize.setting.SettingManager;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
Expand All @@ -20,6 +21,9 @@
@Mixin(ClientPlayerEntity.class)
public abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity {

@Unique
private final SettingManager settingManager = SettingManager.getInstance();

@Unique
private final Sees sees = Sees.getInstance();

Expand All @@ -41,6 +45,7 @@ public ClientPlayerEntityMixin(ClientWorld world, GameProfile profile) {

@Inject(at = @At("TAIL"), method = "tick")
private void onTick(CallbackInfo ci) {
this.settingManager.tick();
this.damageManager.tick(this.getHealth());
this.sleepManager.tick(this.isSleeping(), this.getSleepTimer());
this.taskManager.tick();
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/nl/devpieter/utilize/setting/KeyedSetting.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package nl.devpieter.utilize.setting;

public record KeyedSetting<T>(String key, T value) {
}
167 changes: 167 additions & 0 deletions src/main/java/nl/devpieter/utilize/setting/SettingManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
package nl.devpieter.utilize.setting;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.reflect.TypeToken;
import nl.devpieter.utilize.Utilize;
import nl.devpieter.utilize.setting.interfaces.ISetting;
import org.jetbrains.annotations.Nullable;

import java.io.*;
import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CompletableFuture;

public class SettingManager {

private static SettingManager INSTANCE;

private final Gson gson = new Gson();

private final Duration saveInterval = Duration.ofSeconds(15);
private final HashMap<String, List<KeyedSetting<?>>> saveQueue = new HashMap<>();

private long lastSaveTime = 0;
private CompletableFuture<Boolean> saveFuture = null;

private SettingManager() {
}

public static SettingManager getInstance() {
if (INSTANCE == null) INSTANCE = new SettingManager();
return INSTANCE;
}

public void tick() {
if (this.saveQueue.isEmpty()) return;

long currentTime = System.currentTimeMillis();
if (currentTime - this.lastSaveTime < this.saveInterval.toMillis()) return;

if (this.saveFuture != null && !this.saveFuture.isDone()) return;

this.saveFuture = CompletableFuture.supplyAsync(() -> {
int files = this.saveQueue.size();
int size = this.saveQueue.values().stream().mapToInt(List::size).sum();
Utilize.LOGGER.info("Starting periodic 'setting batch save' for {} files and {} settings", files, size);

for (String path : this.saveQueue.keySet()) {
File file = new File(path);

if (this.saveBatchToFile(file, this.saveQueue.get(path))) continue;
Utilize.LOGGER.error("Failed to save settings batch to file: {}", file.getAbsolutePath());
}

this.lastSaveTime = currentTime;
this.saveQueue.clear();
return true;
});
}

public boolean queueSave(File file, ISetting<?> setting) {
String path = file.getAbsolutePath();
KeyedSetting<?> keyedSetting = setting.asKeyedSetting();

List<KeyedSetting<?>> settingsList = this.saveQueue.getOrDefault(path, new ArrayList<>());
settingsList.removeIf(s -> s.key().equals(keyedSetting.key()));
settingsList.add(keyedSetting);

this.saveQueue.put(path, settingsList);
return true;
}

public boolean queueSave(File file, List<ISetting<?>> settings) {
boolean success = true;

for (ISetting<?> setting : settings) {
if (!queueSave(file, setting)) success = false;
}

return success;
}

public void forceSaveQueue() {
if (this.saveQueue.isEmpty()) return;

int files = this.saveQueue.size();
int size = this.saveQueue.values().stream().mapToInt(List::size).sum();
Utilize.LOGGER.info("Forced starting 'setting batch save' for {} files and {} settings", files, size);

for (String path : this.saveQueue.keySet()) {
File file = new File(path);

if (this.saveBatchToFile(file, this.saveQueue.get(path))) continue;
Utilize.LOGGER.error("Failed to force save settings batch to file: {}", file.getAbsolutePath());
}

this.saveQueue.clear();
}

public <T> boolean loadSetting(File file, ISetting<T> setting) {
List<KeyedSetting<?>> batch = this.readBatchFromFile(file);
return loadSettingFromBatch(setting, batch);
}

public boolean loadSettings(File file, List<ISetting<?>> settings) {
List<KeyedSetting<?>> batch = this.readBatchFromFile(file);
for (ISetting<?> setting : settings) loadSettingFromBatch(setting, batch);

return true;
}

private <T> boolean loadSettingFromBatch(ISetting<T> setting, List<KeyedSetting<?>> batch) {
if (batch == null || batch.isEmpty()) {
setting.setValue(setting.getDefault());
return true;
}

for (KeyedSetting<?> keyedSetting : batch) {
if (!keyedSetting.key().equals(setting.getIdentifier())) continue;

JsonElement jsonElement = gson.toJsonTree(keyedSetting.value());
T value = this.gson.fromJson(jsonElement, setting.getType());

setting.setValue(setting.shouldAllowNull() ? value : value != null ? value : setting.getDefault());
return true;
}

Utilize.LOGGER.warn("Failed to load setting: {} from batch", setting.getIdentifier());
return false;
}

private boolean saveBatchToFile(File file, List<KeyedSetting<?>> settings) {
List<KeyedSetting<?>> currentSettings = this.readBatchFromFile(file);
if (currentSettings == null) currentSettings = new ArrayList<>();

HashMap<String, KeyedSetting<?>> settingsMap = new HashMap<>();
for (KeyedSetting<?> setting : currentSettings) {
settingsMap.put(setting.key(), setting);
}

for (KeyedSetting<?> setting : settings) {
settingsMap.put(setting.key(), setting);
}

currentSettings = new ArrayList<>(settingsMap.values());

try (FileWriter writer = new FileWriter(file)) {
this.gson.toJson(currentSettings, writer);
return true;
} catch (IOException e) {
Utilize.LOGGER.error("Failed to save settings batch to file: {}", file.getAbsolutePath(), e);
return false;
}
}

private @Nullable List<KeyedSetting<?>> readBatchFromFile(File file) {
try (Reader reader = new FileReader(file)) {
return this.gson.fromJson(reader, new TypeToken<List<KeyedSetting<?>>>() {
}.getType());
} catch (IOException e) {
Utilize.LOGGER.error("Failed to read settings batch from file: {}", file.getAbsolutePath(), e);
return null;
}
}
}
49 changes: 49 additions & 0 deletions src/main/java/nl/devpieter/utilize/setting/base/SettingBase.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package nl.devpieter.utilize.setting.base;

import nl.devpieter.utilize.setting.interfaces.ISetting;

public abstract class SettingBase<T> implements ISetting<T> {

private final String identifier;
private final T defaultValue;

private final boolean allowNull;

private T value;

public SettingBase(String identifier, T defaultValue) {
this(identifier, defaultValue, false);
}

public SettingBase(String identifier, T defaultValue, boolean allowNull) {
this.identifier = identifier;
this.defaultValue = defaultValue;
this.value = defaultValue;
this.allowNull = allowNull;
}

@Override
public String getIdentifier() {
return identifier;
}

@Override
public boolean shouldAllowNull() {
return allowNull;
}

@Override
public T getValue() {
return value;
}

@Override
public T getDefault() {
return defaultValue;
}

@Override
public void setValue(T value) {
this.value = value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package nl.devpieter.utilize.setting.interfaces;

import java.lang.reflect.Type;

public interface IBooleanSetting extends ISetting<Boolean> {

@Override
default Type getType() {
return Boolean.class;
}

void toggle();

void setTrue();

void setFalse();
}
Loading