package me.km.snuviscript; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.UUID; import me.hammerle.snuviscript.code.ISnuviLogger; import me.hammerle.snuviscript.code.ISnuviScheduler; import me.hammerle.snuviscript.code.Script; import me.hammerle.snuviscript.code.ScriptManager; import me.km.events.CustomEventCaller; import net.minecraft.entity.player.PlayerEntity; public class Scripts { private final ScriptManager manager; private final ISnuviLogger logger; private CustomEventCaller cec = null; private final HashMap playerScript = new HashMap<>(); private final HashMap> registeredPlayers = new HashMap<>(); private final HashSet scriptCommands = new HashSet<>(); private final Limits entityLimits = new Limits(); public Scripts(ISnuviLogger logger, ISnuviScheduler scheduler) { this.logger = logger; manager = new ScriptManager(logger, scheduler); } public void setCustomEventCaller(CustomEventCaller cec) { this.cec = cec; } public ScriptManager getScriptManager() { return manager; } public ISnuviLogger getLogger() { return logger; } public Limits getEntityLimits() { return entityLimits; } // ------------------------------------------------------------------------- // custom commands // ------------------------------------------------------------------------- public boolean isRegisteredScriptCommand(String s) { return scriptCommands.contains(s); } public void registerScriptCommand(String s) { if(s.equals("script")) { return; } scriptCommands.add(s); } public void unregisterScriptCommand(String s) { scriptCommands.remove(s); } public void clearScriptCommands() { scriptCommands.clear(); } // ------------------------------------------------------------------------- // player script // ------------------------------------------------------------------------- public List getPlayerList(int id) { return registeredPlayers.getOrDefault(id, Collections.EMPTY_LIST); } private List getOrCreatePlayerList(int id) { List list = registeredPlayers.get(id); if(list == null) { list = new ArrayList<>(); registeredPlayers.put(id, list); } return list; } public boolean registerPlayer(Script sc, PlayerEntity p) { if(playerScript.putIfAbsent(p.getUniqueID(), sc.getId()) != null) { return false; } getOrCreatePlayerList(sc.getId()).add(p.getUniqueID()); ScriptVars.setPlayerVars(sc, p); manager.callEvent("player_join", sc, null, null); return true; } public boolean isRegistered(PlayerEntity p) { return playerScript.containsKey(p.getUniqueID()); } public Script getScript(PlayerEntity p) { // check if the player is mapped to a script Integer id = playerScript.get(p.getUniqueID()); if(id == null) { return null; } // player mapping does not necessary mean the script is valid Script sc = manager.getScript(id); if(sc == null) { playerScript.remove(p.getUniqueID()); logger.print(String.format("invalid script of '%s' was removed. (1)", p.getName())); return null; } return sc; } public boolean unregisterPlayer(Script callingScript, PlayerEntity p) { Integer id = playerScript.remove(p.getUniqueID()); if(id == null) { return false; } List list = registeredPlayers.get(id); if(list == null) { return false; } boolean b = list.remove(p.getUniqueID()); if(list.isEmpty()) { Script sc = manager.getScript(id); if(sc == null) { logger.print(String.format("invalid script of '%s' was removed. (2)", p.getName())); return true; } if(sc != callingScript) { manager.callEvent("player_kicked", sc, (innerSc) -> ScriptVars.setPlayerVars(innerSc, p), null); } manager.removeScript(sc); } return b; } public void clearPlayerRegistry() { playerScript.clear(); registeredPlayers.clear(); } // ------------------------------------------------------------------------- // script starting // ------------------------------------------------------------------------- public Script startPlayerScript(PlayerEntity p, String... names) { if(isRegistered(p)) { return null; } Arrays.setAll(names, i -> "scripts/" + names[i] + ".txt"); return manager.startScript(false, sc -> { int id = sc.getId(); playerScript.put(p.getUniqueID(), id); getOrCreatePlayerList(id).add(p.getUniqueID()); }, sc -> { getPlayerList(sc.getId()).forEach(uuid -> playerScript.remove(uuid)); registeredPlayers.remove(sc.getId()); cec.removeScriptData(sc); }, names[0], names); } public Script startScript(String name, String... names) { Arrays.setAll(names, i -> "scripts/" + names[i] + ".txt"); return manager.startScript(true, sc -> { }, sc -> cec.removeScriptData(sc), name == null ? names[0] : name, names); } }