Fixes to some Script Handling

This commit is contained in:
Kam committed 2026-03-02 16:38:35 -05:00
1 parent 702dec9c40
commit dfa6ccb350
11 files changed
+142 -44

No files matched your search

@@ -158,7 +158,9 @@ public class GuiScript extends GuiScriptInterface {
container == null ? "" : container.script);
}
activeArea.setLanguage(script.getLanguage());
// Use the container's language for syntax highlighting, fall back to handler default
String language = (container != null) ? container.getLanguage() : script.getLanguage();
activeArea.setLanguage(language);
activeArea.setScriptContext(getScriptContext());
// Setup fullscreen key binding
@@ -211,16 +213,19 @@ public class GuiScript extends GuiScriptInterface {
addButton(new GuiNpcButton(105, guiLeft + 60, guiTop + 4, 80, 20,
consoleOptions.toArray(new String[0]), activeConsole));
addLabel(new GuiNpcLabel(1, "script.language", guiLeft + 232, guiTop + 30));
addLabel(new GuiNpcLabel(1, "script.default", guiLeft + 232, guiTop + 30));
List<String> languageOptions = getLanguageOptions();
addButton(new GuiNpcButton(103, guiLeft + 294, guiTop + 25, 80, 20,
languageOptions.toArray(new String[0]), getLanguageIndex(languageOptions)));
getButton(103).enabled = languageOptions.size() > 0;
addLabel(new GuiNpcLabel(2, "gui.enabled", guiLeft + 232, guiTop + 53));
addButton(new GuiNpcButton(104, guiLeft + 294, guiTop + 48, 50, 20,
new String[]{"gui.no", "gui.yes"}, script.enabled ? 1 : 0));
// Disable language/enabled controls until server data actually arrives
getButton(103).enabled = serverDataReceived && languageOptions.size() > 0;
getButton(104).enabled = serverDataReceived;
if (MinecraftServer.getServer() != null)
addButton(new GuiNpcButton(106, guiLeft + 232, guiTop + 71, 150, 20, "script.openfolder"));
}
@@ -309,9 +314,13 @@ public class GuiScript extends GuiScriptInterface {
}
if (guibutton.id == 107) {
ScriptContainer container = getCurrentContainer();
if (container == null)
script.setNPCScript(activeTab, container = new ScriptContainer(this.script));
setSubGui(new GuiScriptList(languages.get(script.scriptLanguage), container));
if (container == null) {
container = new ScriptContainer(this.script);
container.setLanguage(script.getLanguage());
script.setNPCScript(activeTab, container);
}
String lang = container.getLanguage();
setSubGui(new GuiScriptList(languages.get(lang), container));
}
}
@@ -319,8 +328,11 @@ public class GuiScript extends GuiScriptInterface {
protected void setScript() {
if (showScript) {
ScriptContainer container = getCurrentContainer();
if (container == null)
script.setNPCScript(activeTab, container = new ScriptContainer(this.script));
if (container == null) {
container = new ScriptContainer(this.script);
container.setLanguage(script.getLanguage());
script.setNPCScript(activeTab, container);
}
String text = getTextField(2).getText();
text = text.replace("\r\n", "\n");
text = text.replace("\r", "\n");
@@ -50,6 +50,7 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb
protected int scriptLimit = 1;
public List<String> hookList = new ArrayList<String>();
protected boolean loaded = false;
protected boolean serverDataReceived = false;
protected Map<Integer, GuiScriptTextArea> textAreas = new HashMap<>();
protected GuiScreen parent;
@@ -300,9 +301,12 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb
this.addButton(new GuiNpcButton(100, left1, this.guiTop + 21 + yoffset, 60, 20, "gui.copy"));
this.addButton(new GuiNpcButton(105, left1 + 61, this.guiTop + 21 + yoffset, 60, 20, "gui.remove"));
// Language toggle button (only if handler supports Janino and there is more than one option)
if (handler.supportsJanino() && getLanguageOptions().size() > 1 && container != null) {
this.addButton(new GuiNpcButton(113, left1, this.guiTop + 42 + yoffset, 121, 20, container.getLanguage()));
// Per-tab language button — cycles through all available languages
List<String> langOptions = getLanguageOptions();
if (langOptions.size() > 1 && container != null) {
int langIdx = getContainerLanguageIndex(langOptions, container);
this.addButton(new GuiNpcButton(113, left1, this.guiTop + 42 + yoffset, 121, 20,
langOptions.toArray(new String[0]), langIdx));
}
this.addButton(new GuiNpcButton(107, left1, this.guiTop + 66 + yoffset, 80, 20, "script.loadscript"));
@@ -331,16 +335,20 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb
int var9 = this.guiLeft + this.xSize - 150;
this.addButton(new GuiNpcButton(100, var9, this.guiTop + 125, 60, 20, "gui.copy"));
this.addButton(new GuiNpcButton(102, var9, this.guiTop + 146, 60, 20, "gui.clear"));
this.addLabel(new GuiNpcLabel(1, "script.language", var9, this.guiTop + 15));
this.addLabel(new GuiNpcLabel(1, "script.default", var9, this.guiTop + 15));
List<String> languageOptions = getLanguageOptions();
this.addButton(new GuiNpcButton(103, var9 + 60, this.guiTop + 10, 80, 20,
languageOptions.toArray(new String[0]),
this.getLanguageIndex(languageOptions)));
this.getButton(103).enabled = languageOptions.size() > 0;
this.addLabel(new GuiNpcLabel(2, "gui.enabled", var9, this.guiTop + 36));
this.addButton(new GuiNpcButton(104, var9 + 60, this.guiTop + 31, 50, 20,
new String[]{"gui.no", "gui.yes"}, this.handler.getEnabled() ? 1 : 0));
// Disable language/enabled controls until server data actually arrives
// (serverDataReceived is only set in loadLanguagesData, not by getLanguageOptions injecting Java)
this.getButton(103).enabled = serverDataReceived && languageOptions.size() > 0;
this.getButton(104).enabled = serverDataReceived;
if (this.player.worldObj.isRemote) {
this.addButton(new GuiNpcButton(106, var9, this.guiTop + 55, 150, 20, "script.openfolder"));
}
@@ -467,6 +475,26 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb
return 0;
}
/**
* Finds the index of a container's language within the available options.
* Used for the per-tab language button (113).
*
* @param languageOptions The list of available languages.
* @param container The script unit whose language to find.
* @return The 0-based index, or 0 if not found.
*/
protected int getContainerLanguageIndex(List<String> languageOptions, IScriptUnit container) {
if (languageOptions == null || languageOptions.isEmpty() || container == null)
return 0;
String current = container.getLanguage();
for (int i = 0; i < languageOptions.size(); i++) {
if (current != null && languageOptions.get(i).equalsIgnoreCase(current))
return i;
}
return 0;
}
/**
* Retrieves the list of available scripting languages for this handler.
* <p>
@@ -591,13 +619,13 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb
if (guibutton.id == scriptLimit) {
if (handler.isSingleContainer()) {
if (handler.getSingleScript() == null) {
handler.addScriptUnit(new ScriptContainer(handler));
handler.addScriptUnit(createDefaultScriptUnit());
} else {
this.setScript();
}
this.activeTab = 1;
} else {
handler.addScriptUnit(new ScriptContainer(this.handler));
handler.addScriptUnit(createDefaultScriptUnit());
this.activeTab = this.handler.getScripts().size();
}
this.initGui();
@@ -655,43 +683,47 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb
if (guibutton.id == 107) {
IScriptUnit container = getCurrentContainer();
if (container == null) {
container = new ScriptContainer(this.handler);
container = createDefaultScriptUnit();
handler.addScriptUnit(container);
}
String language = container != null ? container.getLanguage() : this.handler.getLanguage();
String language = container.getLanguage();
this.setSubGui(new EventGuiScriptList((List) this.languages.get(language), container));
}
// Language toggle button - switch between ECMAScript and Java
// Per-tab language cycling button
if (guibutton.id == 113) {
String selectedLanguage = ((GuiNpcButton) guibutton).displayString;
int idx = getActiveScriptIndex();
if (idx >= 0 && idx < handler.getScripts().size()) {
IScriptUnit currentUnit = handler.getScripts().get(idx);
IScriptUnit newUnit;
boolean currentIsJanino = currentUnit.isJanino();
boolean targetIsJanino = "Java".equals(selectedLanguage);
if (currentUnit.isJanino()) {
// Switch from Java to ECMAScript
newUnit = new ScriptContainer(handler);
if (currentIsJanino && !targetIsJanino) {
// Switch from Java to a non-Java language
IScriptUnit newUnit = new ScriptContainer(handler);
newUnit.setScript(currentUnit.getScript());
newUnit.setExternalScripts(new ArrayList<>(currentUnit.getExternalScripts()));
} else {
// Switch from ECMAScript to Java
newUnit = handler.createJaninoScriptUnit();
handler.replaceScriptUnit(idx, newUnit);
textAreas.remove(idx);
initGui();
} else if (!currentIsJanino && targetIsJanino) {
// Switch from non-Java to Java
IScriptUnit newUnit = handler.createJaninoScriptUnit();
if (newUnit != null) {
newUnit.setScript(currentUnit.getScript());
newUnit.setExternalScripts(new ArrayList<>(currentUnit.getExternalScripts()));
} else {
return; // Handler doesn't support Janino
handler.replaceScriptUnit(idx, newUnit);
textAreas.remove(idx);
initGui();
}
} else if (!currentIsJanino) {
// Switch between non-Java languages (e.g., ECMAScript to Lua)
currentUnit.setLanguage(selectedLanguage);
GuiScriptTextArea area = getActiveScriptArea();
if (area != null) area.setLanguage(selectedLanguage);
}
handler.replaceScriptUnit(idx, newUnit);
// Clear the cached text area so it recreates with new language
textAreas.remove(idx);
// Reinitialize the GUI
initGui();
}
}
}
@@ -701,7 +733,7 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb
IScriptUnit container = getCurrentContainer();
if (container == null) {
container = new ScriptContainer(this.handler);
container = createDefaultScriptUnit();
handler.addScriptUnit(container);
}
@@ -771,6 +803,7 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb
}
this.languages = languages;
this.serverDataReceived = true;
this.initGui();
}
@@ -820,6 +853,22 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb
super.close();
}
/**
* Create a new script unit using the handler's default language.
* If default is Java, creates a JaninoScript; otherwise a ScriptContainer
* with its language set to the handler's default.
*/
protected IScriptUnit createDefaultScriptUnit() {
String defaultLang = handler.getLanguage();
if ("Java".equals(defaultLang)) {
IScriptUnit unit = handler.createJaninoScriptUnit();
if (unit != null) return unit;
}
ScriptContainer sc = new ScriptContainer(handler);
sc.setLanguage(defaultLang);
return sc;
}
// ==================== FULLSCREEN METHODS ====================
/**
@@ -46,6 +46,12 @@ public class ScriptContainer implements IScriptUnit {
private CompiledScript compScript = null;
private final HashMap<String, ScriptObjectMirror> cachedFunctions = new HashMap<>();
/**
* Persisted per-container language. Null means inherit from handler default.
* Separate from currentScriptLanguage which is the engine cache.
*/
private String language = null;
public ScriptContainer(IScriptHandler handler) {
this.handler = handler;
}
@@ -68,6 +74,12 @@ public class ScriptContainer implements IScriptUnit {
this.console = NBTTags.GetLongStringMap(compound.getTagList("Console", 10));
this.scripts = NBTTags.getStringList(compound.getTagList("ScriptList", 10));
this.lastCreated = 0L;
// Read per-container language (empty string or missing = inherit from handler)
if (compound.hasKey("ContainerLanguage")) {
String lang = compound.getString("ContainerLanguage");
this.language = lang.isEmpty() ? null : lang;
}
}
public NBTTagCompound writeToNBT(NBTTagCompound compound) {
@@ -98,6 +110,11 @@ public class ScriptContainer implements IScriptUnit {
//compound.setString("Type", this.type);
compound.setTag("Console", NBTTags.NBTLongStringMap(this.console));
compound.setTag("ScriptList", NBTTags.nbtStringList(this.scripts));
// Persist per-container language if explicitly set
if (this.language != null) {
compound.setString("ContainerLanguage", this.language);
}
return compound;
}
@@ -169,7 +186,7 @@ public class ScriptContainer implements IScriptUnit {
if (!CustomNpcs.proxy.isScriptingEnabled() || errored || !hasCode() || unknownFunctions.contains(type))
return;
this.setEngine(handler.getLanguage());
this.setEngine(this.getLanguage());
if (engine == null)
return;
@@ -308,18 +325,15 @@ public class ScriptContainer implements IScriptUnit {
@Override
public String getLanguage() {
// If a specific language is set for this container, use it
// Otherwise fall back to the handler's language
if (currentScriptLanguage != null) {
return currentScriptLanguage;
}
return handler != null ? handler.getLanguage() : "ECMAScript";
// Return persisted per-container language, defaulting to ECMAScript.
// This is separate from currentScriptLanguage which is the engine cache.
return this.language != null ? this.language : "ECMAScript";
}
@Override
public void setLanguage(String language) {
if (!Objects.equals(this.currentScriptLanguage, language)) {
this.currentScriptLanguage = language;
if (!Objects.equals(this.language, language)) {
this.language = language;
this.evaluated = false;
}
}
@@ -18,6 +18,7 @@ import noppes.npcs.constants.ScriptContext;
import noppes.npcs.controllers.ScriptContainer;
import noppes.npcs.controllers.ScriptController;
import noppes.npcs.controllers.ScriptHookController;
import noppes.npcs.janino.EventJaninoScript;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
@@ -161,6 +162,11 @@ public class ForgeDataScript extends MultiScriptHandler {
ForgeScriptPacket.Save(index, totalCount, nbt);
}
@Override
public IScriptUnit createJaninoScriptUnit() {
return new EventJaninoScript(ScriptContext.FORGE);
}
@Override
public boolean isClient() {
return false;
@@ -8,6 +8,7 @@ import noppes.npcs.api.entity.ICustomNpc;
import noppes.npcs.constants.ScriptContext;
import noppes.npcs.controllers.ScriptController;
import noppes.npcs.entity.EntityNPCInterface;
import noppes.npcs.janino.EventJaninoScript;
import noppes.npcs.scripted.NpcAPI;
import noppes.npcs.util.ScriptToStringHelper;
@@ -47,6 +48,11 @@ public class GlobalNPCDataScript extends MultiScriptHandler {
lastNpcUpdate = ScriptController.Instance.lastGlobalNpcUpdate;
}
@Override
public IScriptUnit createJaninoScriptUnit() {
return new EventJaninoScript(ScriptContext.NPC);
}
@Override
public void requestData() {
GlobalNPCScriptPacket.Get();
@@ -167,6 +167,12 @@ public class PlayerDataScript extends MultiScriptHandler {
return ScriptController.Instance.playerScripts.scriptLanguage;
}
@Override
public void setLanguage(String lang) {
ScriptController.Instance.playerScripts.scriptLanguage = lang;
this.scriptLanguage = lang;
}
@Override
public String noticeString() {
if (this.player == null) {