Skip to content

Commit

Permalink
move NoteManager, server flags, shutdown event, etc. to core
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmonkey4eva committed Oct 19, 2021
1 parent fd8de4e commit a57adcb
Show file tree
Hide file tree
Showing 14 changed files with 420 additions and 29 deletions.
40 changes: 38 additions & 2 deletions src/main/java/com/denizenscript/denizencore/DenizenCore.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.denizenscript.denizencore.events.OldEventManager;
import com.denizenscript.denizencore.events.ScriptEvent;
import com.denizenscript.denizencore.events.core.*;
import com.denizenscript.denizencore.flags.SavableMapFlagTracker;
import com.denizenscript.denizencore.objects.notable.NoteManager;
import com.denizenscript.denizencore.scripts.ScriptHelper;
import com.denizenscript.denizencore.scripts.ScriptRegistry;
import com.denizenscript.denizencore.scripts.commands.CommandRegistry;
Expand All @@ -13,6 +15,7 @@
import com.denizenscript.denizencore.utilities.debugging.VerySlowWarning;
import com.denizenscript.denizencore.utilities.scheduling.Schedulable;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
Expand All @@ -26,8 +29,14 @@ public class DenizenCore {

public final static String VERSION;

static CommandRegistry commandRegistry;
static ScriptEngine scriptEngine;
public static CommandRegistry commandRegistry;
public static ScriptEngine scriptEngine;

public final static long startTime = System.currentTimeMillis();

public static SavableMapFlagTracker serverFlagMap;

public static long lastReloadTime;

public static CommandRegistry getCommandRegistry() {
return commandRegistry;
Expand Down Expand Up @@ -89,6 +98,31 @@ public static void init(DenizenImplementation implementation) {
ScriptEvent.registerCoreEvents();
}

/**
* Call to reload anything that was saved, especially after init.
*/
public static void reloadSaves() {
serverFlagMap = SavableMapFlagTracker.loadFlagFile(new File(getImplementation().getDataFolder(), "server_flags").getPath());
}

/**
* Call to save anything that needs to be saved, especially before shutdown.
*/
public static void saveAll() {
NoteManager.save();
serverFlagMap.saveToFile(new File(getImplementation().getDataFolder(), "server_flags").getPath());
}

/**
* Must be called last: performs final shutdowns / saves / etc.
*/
public static void shutdown() {
ShutdownScriptEvent.instance.fire();
saveAll();
logInterceptor.standardOutput();
commandRegistry.disableCoreMembers();
}

/**
* Call postLoadScripts after.
*/
Expand All @@ -115,10 +149,12 @@ public static void preloadScripts() {
*/
public static void postLoadScripts() {
try {
NoteManager.reload();
ScriptRegistry.postLoadScripts();
OldEventManager.scanWorldEvents();
ScriptEvent.reload();
implementation.onScriptReload();
lastReloadTime = System.currentTimeMillis();
}
catch (Exception ex) {
implementation.debugMessage("Error loading scripts:");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,6 @@ public interface DenizenImplementation {

String scriptQueueSpeed();

AbstractFlagTracker getServerFlags();

TagContext getTagContext(ScriptContainer container);

TagContext getTagContext(ScriptEntry entry);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public static void registerCoreEvents() {
registerScriptEvent(new ReloadScriptsScriptEvent());
registerScriptEvent(new ScriptGeneratesErrorScriptEvent());
registerScriptEvent(new ServerGeneratesExceptionScriptEvent());
registerScriptEvent(new ShutdownScriptEvent());
registerScriptEvent(new SystemTimeScriptEvent());
registerScriptEvent(new TickScriptEvent());
}
Expand Down Expand Up @@ -432,7 +433,7 @@ public boolean matches(ScriptPath path) {
String flagSwitch = path.switches.get("server_flagged");
if (flagSwitch != null) {
for (String flag : CoreUtilities.split(flagSwitch, '|')) {
if (!DenizenCore.getImplementation().getServerFlags().hasFlag(flag)) {
if (!DenizenCore.serverFlagMap.hasFlag(flag)) {
return false;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.denizenscript.denizencore.events.core;

import com.denizenscript.denizencore.events.ScriptEvent;

public class ShutdownScriptEvent extends ScriptEvent {

// <--[event]
// @Events
// shutdown
//
// @Regex ^on shutdown$
//
// @Group Server
//
// @Warning not all plugins will be loaded and delayed scripts will be dropped.
// Also note that this event is not guaranteed to always run (eg if the server crashes).
//
// @Triggers when the server is shutting down.
//
// -->

public ShutdownScriptEvent() {
instance = this;
}

public static ShutdownScriptEvent instance;

@Override
public boolean couldMatch(ScriptPath path) {
if (!path.eventLower.startsWith("shutdown")) {
return false;
}
return true;
}

@Override
public String getName() {
return "ServerShutdown";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ public boolean isUnique() {

@Override
public AbstractFlagTracker getFlagTracker() {
return new RedirectionFlagTracker(DenizenCore.getImplementation().getServerFlags(), "__scripts." + name.replace(".", "&dot"));
return new RedirectionFlagTracker(DenizenCore.serverFlagMap, "__scripts." + name.replace(".", "&dot"));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ public int millisecondComponent() {

@Override
public AbstractFlagTracker getFlagTracker() {
return new RedirectionFlagTracker(DenizenCore.getImplementation().getServerFlags(), "__time." + millis());
return new RedirectionFlagTracker(DenizenCore.serverFlagMap, "__time." + millis());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,8 @@ public interface Notable {

boolean isUnique();

/**
* Gets the object to be saved to the notables.yml.
* This should either be a String, or a ConfigurationSerializable object.
*
* @return the object to be saved
*/
Object getSaveObject();

/**
* Saves the object in the NotableManager. Notable objects are saved through
* a server restart.
*
* @param id the id of the notable
*/
void makeUnique(String id);

void forget();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
package com.denizenscript.denizencore.objects.notable;

import com.denizenscript.denizencore.DenizenCore;
import com.denizenscript.denizencore.flags.FlaggableObject;
import com.denizenscript.denizencore.flags.SavableMapFlagTracker;
import com.denizenscript.denizencore.objects.ObjectFetcher;
import com.denizenscript.denizencore.objects.ObjectTag;
import com.denizenscript.denizencore.tags.core.EscapeTagBase;
import com.denizenscript.denizencore.utilities.CoreUtilities;
import com.denizenscript.denizencore.utilities.YamlConfiguration;
import com.denizenscript.denizencore.utilities.debugging.Debug;
import com.denizenscript.denizencore.utilities.text.StringHolder;

import java.io.File;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class NoteManager {

public static HashMap<String, Notable> nameToObject = new HashMap<>();
public static HashMap<Notable, String> objectToName = new HashMap<>();
public static HashMap<Class, HashSet<Notable>> notesByType = new HashMap<>();

public static boolean isSaved(Notable object) {
return objectToName.containsKey(object);
}

public static boolean isExactSavedObject(Notable object) {
String id = objectToName.get(object);
if (id == null) {
return false;
}
return nameToObject.get(id) == object;
}

public static Notable getSavedObject(String id) {
return nameToObject.get(CoreUtilities.toLowerCase(id));
}

public static String getSavedId(Notable object) {
return objectToName.get(object);
}

public static void saveAs(Notable object, String id) {
if (object == null) {
return;
}
id = CoreUtilities.toLowerCase(id);
Notable noted = nameToObject.get(id);
if (noted != null) {
noted.forget();
}
nameToObject.put(id, object);
objectToName.put(object, id);
notesByType.get(object.getClass()).add(object);
}

public static Notable remove(String id) {
id = CoreUtilities.toLowerCase(id);
Notable obj = nameToObject.get(id);
if (obj == null) {
return null;
}
nameToObject.remove(id);
objectToName.remove(obj);
notesByType.get(obj.getClass()).remove(obj);
return obj;
}

public static void remove(Notable obj) {
String id = objectToName.get(obj);
nameToObject.remove(id);
objectToName.remove(obj);
notesByType.get(obj.getClass()).remove(obj);
}

public static <T extends Notable> Set<T> getAllType(Class<T> type) {
return (Set<T>) notesByType.get(type);
}

private static void loadFromConfig() {
nameToObject.clear();
for (Set set : notesByType.values()) {
set.clear();
}
objectToName.clear();
for (StringHolder key : getSaveConfig().getKeys(false)) {
Class<? extends ObjectTag> clazz = namesToTypes.get(key.str);
YamlConfiguration section = getSaveConfig().getConfigurationSection(key.str);
if (section == null) {
continue;
}
for (StringHolder noteNameHolder : section.getKeys(false)) {
String noteName = noteNameHolder.str;
String note = EscapeTagBase.unEscape(noteName.replace("DOT", "."));
String objText;
String flagText = null;
Object rawPart = section.get(noteName);
if (rawPart instanceof YamlConfiguration || rawPart instanceof Map) {
objText = section.getConfigurationSection(noteName).getString("object");
flagText = section.getConfigurationSection(noteName).getString("flags");
}
else {
objText = section.getString(noteName);
}
Notable obj = (Notable) ObjectFetcher.getObjectFrom(clazz, objText, CoreUtilities.errorButNoDebugContext);
if (obj != null) {
obj.makeUnique(note);
if (flagText != null && obj instanceof FlaggableObject) {
((FlaggableObject) getSavedObject(note)).reapplyTracker(new SavableMapFlagTracker(flagText));
}
}
else {
Debug.echoError("Note '" + note + "' failed to load!");
}
}
}
}

private static void saveToConfig() {
YamlConfiguration saveConfig = getSaveConfig();
for (StringHolder key : saveConfig.getKeys(false)) {
saveConfig.set(key.str, null);
}
for (Map.Entry<String, Notable> note : nameToObject.entrySet()) {
try {
saveConfig.set(typesToNames.get(getClass(note.getValue())) + "." + EscapeTagBase.escape(CoreUtilities.toLowerCase(note.getKey())), note.getValue().getSaveObject());
}
catch (Exception e) {
Debug.echoError("Notable '" + note.getKey() + "' failed to save!");
Debug.echoError(e);
}
}
}

private static <T extends Notable> Class<T> getClass(Notable note) {
for (Class clazz : typesToNames.keySet()) {
if (clazz.isInstance(note)) {
return clazz;
}
}
return null;
}

private static YamlConfiguration saveConfig = null;
private static String saveFilePath = null;

public static void reload() {
if (saveFilePath == null) {
saveFilePath = new File(DenizenCore.getImplementation().getDataFolder(), "notables.yml").getPath();
}
String rawFileData = CoreUtilities.journallingLoadFile(saveFilePath);
saveConfig = rawFileData == null ? new YamlConfiguration() : YamlConfiguration.load(rawFileData);
loadFromConfig();
}

public static YamlConfiguration getSaveConfig() {
if (saveConfig == null) {
reload();
}
return saveConfig;
}

public static void save() {
if (saveConfig == null || saveFilePath == null) {
return;
}
saveToConfig();
if (nameToObject.isEmpty()) {
if (new File(saveFilePath).exists()) {
new File(saveFilePath).delete();
}
}
else {
CoreUtilities.journallingFileSave(saveFilePath, saveConfig.saveToString(false));
}
}

///////////////////
// Note Annotation Handler
///////////////////

public static Map<Class, String> typesToNames = new HashMap<>();
public static Map<String, Class> namesToTypes = new HashMap<>();

public static void registerObjectTypeAsNotable(Class notable) {
for (Method method : notable.getMethods()) {
if (method.isAnnotationPresent(Note.class)) {
String note = method.getAnnotation(Note.class).value();
typesToNames.put(notable, note);
namesToTypes.put(note, notable);
notesByType.put(notable, new HashSet<>());
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ public void registerCoreCommands() {
// Intentionally do not register the DebugInvalidCommand
registerCommand(EventCommand.class);
registerCommand(FlagCommand.class);
registerCommand(NoteCommand.class);
registerCommand(ReloadCommand.class);
registerCommand(SQLCommand.class);
registerCommand(WebGetCommand.class);
Expand Down
Loading

0 comments on commit a57adcb

Please sign in to comment.