Advertisement
tomdodd4598

Untitled

Apr 28th, 2021
956
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 16.48 KB | None | 0 0
  1. package crafttweaker.runtime;
  2.  
  3. import crafttweaker.*;
  4. import crafttweaker.api.network.NetworkSide;
  5. import crafttweaker.preprocessor.*;
  6. import crafttweaker.runtime.events.*;
  7. import crafttweaker.socket.SingleError;
  8. import crafttweaker.util.*;
  9. import crafttweaker.zenscript.*;
  10. import stanhebben.zenscript.*;
  11. import stanhebben.zenscript.compiler.IEnvironmentGlobal;
  12. import stanhebben.zenscript.parser.ParseException;
  13.  
  14. import java.io.*;
  15. import java.nio.charset.StandardCharsets;
  16. import java.util.*;
  17.  
  18. import static stanhebben.zenscript.ZenModule.*;
  19.  
  20. /**
  21.  * @author Stan Hebben
  22.  */
  23. public class CrTTweaker implements ITweaker {
  24.    
  25.     private static final String defaultLoaderName = "crafttweaker";
  26.     private static boolean DEBUG = false;
  27.     private final List<IAction> actions = new ArrayList<>();
  28.    
  29.     private final List<ScriptLoader> loaders = new ArrayList<>();
  30.    
  31.     /**
  32.      * List of all event subscribers
  33.      */
  34.     private final EventList<CrTLoaderLoadingEvent.Started> CRT_LOADING_STARTED_EVENT_EVENT_LIST = new EventList<>();
  35.     private final EventList<CrTLoaderLoadingEvent.Finished> CRT_LOADING_FINISHED_EVENT_EVENT_LIST = new EventList<>();
  36.     private final EventList<CrTLoaderLoadingEvent.Aborted> CRT_LOADING_ABORTED_EVENT_EVENT_LIST = new EventList<>();
  37.     private final EventList<CrTScriptLoadingEvent.Pre> CRT_LOADING_SCRIPT_PRE_EVENT_LIST = new EventList<>();
  38.     private final EventList<CrTScriptLoadingEvent.Post> CRT_LOADING_SCRIPT_POST_EVENT_LIST = new EventList<>();
  39.     private NetworkSide networkSide = NetworkSide.INVALID_SIDE;
  40.     /**
  41.      * PreprocessorManager, deals with all preprocessor Actions
  42.      */
  43.     private PreprocessorManager preprocessorManager = new PreprocessorManager();
  44.     private IScriptProvider scriptProvider;
  45.    
  46.    
  47.     public CrTTweaker() {
  48.         PreprocessorManager.registerOwnPreprocessors(preprocessorManager);
  49.     }
  50.    
  51.     @Override
  52.     public void apply(IAction action) {
  53.         if(!action.validate()) {
  54.             CraftTweakerAPI.logError("Action could not be applied", new UnsupportedOperationException(action.describeInvalid()));
  55.             return;
  56.         }
  57.         String describe = action.describe();
  58.         if(describe != null && !describe.isEmpty()) {
  59.             CraftTweakerAPI.logInfo(describe);
  60.         }
  61.         action.apply();
  62.         actions.add(action);
  63.     }
  64.    
  65.     @Override
  66.     public void setScriptProvider(IScriptProvider provider) {
  67.         scriptProvider = provider;
  68.     }
  69.    
  70.     @Override
  71.     public void load() {
  72.         loadScript(false, defaultLoaderName);
  73.     }
  74.    
  75.    
  76.     @Override
  77.     public boolean loadScript(boolean isSyntaxCommand, String loaderName) {
  78.         return loadScript(isSyntaxCommand, loaderName, null, false);
  79.     }
  80.    
  81.     private List<ScriptFile> loadPreprocessor(boolean isSyntaxCommand) {
  82.         List<ScriptFile> scriptFiles = collectScriptFiles(isSyntaxCommand);
  83.        
  84.         // preprocessor magic
  85.         for(ScriptFile scriptFile : scriptFiles) {
  86.             scriptFile.addAll(preprocessorManager.checkFileForPreprocessors(scriptFile));
  87.         }
  88.        
  89.         scriptFiles.sort(PreprocessorManager.SCRIPT_FILE_COMPARATOR);
  90.        
  91.         return scriptFiles;
  92.     }
  93.    
  94.    
  95.     public boolean loadScript(boolean isSyntaxCommand, List<SingleError> parseExceptions, boolean isLinter, String... loaderNames) {
  96.         return loadScript(isSyntaxCommand, getOrAddLoader(loaderNames).removeDelay(loaderNames), parseExceptions, isLinter);
  97.     }
  98.    
  99.     public boolean loadScript(boolean isSyntaxCommand, String loaderName, List<SingleError> parseExceptions, boolean isLinter) {
  100.         return loadScript(isSyntaxCommand, parseExceptions, isLinter, loaderName);
  101.     }
  102.    
  103.     @Override
  104.     public void loadScript(boolean isSyntaxCommand, ScriptLoader loader) {
  105.         loadScript(isSyntaxCommand, loader, null, false);
  106.     }
  107.    
  108.     @SuppressWarnings("deprecation")
  109.     private boolean loadScript(boolean isSyntaxCommand, ScriptLoader loader, List<SingleError> parseExceptions, boolean isLinter) {
  110.         if (isSyntaxCommand) {
  111.             CraftTweakerAPI.setSuppressErrorFlag(SuppressErrorFlag.FORCED);
  112.         }
  113.  
  114.         if(loader == null) {
  115.             CraftTweakerAPI.logError("Error when trying to load with a null loader");
  116.             return false;
  117.         }
  118.         CraftTweakerAPI.logInfo("Loading scripts for loader with names " + loader.toString());
  119.         if(loader.isLoaded() && !isSyntaxCommand) {
  120.             CraftTweakerAPI.logDefault("Skipping loading for loader " + loader + " since it's already been loaded");
  121.             return false;
  122.         }
  123.        
  124.         if(loader.isDelayed() && !isSyntaxCommand) {
  125.             CraftTweakerAPI.logDefault("Skipping loading for loader " + loader + " since its execution is being delayed by another mod.");
  126.             return false;
  127.         }
  128.        
  129.         if(loader.getLoaderStage() == ScriptLoader.LoaderStage.INVALIDATED) {
  130.             CraftTweakerAPI.logWarning("Skipping loading for loader " + loader + " since it's become invalidated");
  131.             return false;
  132.         }
  133.        
  134.        
  135.         loader.setLoaderStage(ScriptLoader.LoaderStage.LOADING);
  136.         if(!isLinter)
  137.             CRT_LOADING_STARTED_EVENT_EVENT_LIST.publish(new CrTLoadingStartedEvent(loader, isSyntaxCommand, networkSide));
  138.        
  139.         preprocessorManager.clean();
  140.        
  141.         Set<String> executed = new HashSet<>();
  142.         boolean loadSuccessful = true;
  143.        
  144.         List<ScriptFile> scriptFiles = loadPreprocessor(isSyntaxCommand);
  145.        
  146.         // prepare logger
  147.         ((CrtStoringErrorLogger) GlobalRegistry.getErrors()).clear();
  148.        
  149.        
  150.         Map<String, byte[]> classes = new HashMap<>();
  151.         IEnvironmentGlobal environmentGlobal = GlobalRegistry.makeGlobalEnvironment(classes, loader.getMainName());
  152.        
  153.         // ZS magic
  154.         long totalTime = System.currentTimeMillis();
  155.         for(ScriptFile scriptFile : scriptFiles) {
  156.             // check for loader
  157.             final String loaderName = loader.getMainName();
  158.            
  159.            
  160.             if(!loader.canExecute(scriptFile.getLoaderNames())) {
  161.                 if(!isSyntaxCommand)
  162.                     CraftTweakerAPI.logDefault(getTweakerDescriptor(loaderName) + ": Skipping file " + scriptFile + " as we are currently loading with a different loader");
  163.                 continue;
  164.             }
  165.            
  166.             // check for network side
  167.             if(!scriptFile.shouldBeLoadedOn(networkSide)) {
  168.                 CraftTweakerAPI.logDefault(getTweakerDescriptor(loaderName) + ": Skipping file " + scriptFile + " as we are on the wrong side of the Network");
  169.                 continue;
  170.             }
  171.            
  172.             // prevent double execution
  173.             if(!executed.contains(scriptFile.getEffectiveName())) {
  174.                 executed.add(scriptFile.getEffectiveName());
  175.                
  176.                 //TODO: Only print if not syntax command?
  177.                 //if(!isSyntaxCommand)
  178.                 CraftTweakerAPI.logDefault(getTweakerDescriptor(loaderName) + ": Loading Script: " + scriptFile);
  179.                
  180.                 ZenParsedFile zenParsedFile = null;
  181.                 String filename = scriptFile.getEffectiveName();
  182.                 String className = extractClassName(filename);
  183.                
  184.                 if(!isLinter)
  185.                     CRT_LOADING_SCRIPT_PRE_EVENT_LIST.publish(new CrTLoadingScriptEventPre(filename));
  186.                
  187.                 // start reading of the scripts
  188.                 ZenTokener parser = null;
  189.                 try(Reader reader = new InputStreamReader(new BufferedInputStream(scriptFile.open()), StandardCharsets.UTF_8)) {
  190.                     preprocessorManager.postLoadEvent(new CrTScriptLoadEvent(scriptFile));
  191.                    
  192.                     // blocks the parsing of the script
  193.                     if(scriptFile.isParsingBlocked()) {
  194.                         if (!isLinter)
  195.                             CRT_LOADING_SCRIPT_POST_EVENT_LIST.publish(new CrTLoadingScriptEventPost(filename));
  196.                         continue;
  197.                     }
  198.                    
  199.                     parser = new ZenTokener(reader, environmentGlobal.getEnvironment(), filename, scriptFile.areBracketErrorsIgnored());
  200.                     zenParsedFile = new ZenParsedFile(filename, className, parser, environmentGlobal);
  201.                    
  202.                 } catch(IOException ex) {
  203.                     CraftTweakerAPI.logError(getTweakerDescriptor(loaderName) + ": Could not load script " + scriptFile + ": " + ex.getMessage());
  204.                     loadSuccessful = false;
  205.                 } catch(ParseException ex) {
  206.                     CraftTweakerAPI.logError(getTweakerDescriptor(loaderName) + ": Error parsing " + ex.getFile().getFileName() + ":" + ex.getLine() + " -- " + ex.getExplanation());
  207.                     loadSuccessful = false;
  208.                     if(parseExceptions != null)
  209.                         parseExceptions.add(new SingleError(ex.getFile().getFileName(), ex.getLine(), ex.getLineOffset(), ex.getExplanation(), SingleError.Level.ERROR));
  210.                 } catch(Exception ex) {
  211.                     CraftTweakerAPI.logError(getTweakerDescriptor(loaderName) + ": Error loading " + scriptFile + ": " + ex.toString(), ex);
  212.                     if(parser != null && parseExceptions != null)
  213.                         parseExceptions.add(new SingleError(parser.getFile().getFileName(), parser.getLine(), parser.getLineOffset(), "Generic ERROR", SingleError.Level.ERROR));
  214.                     loadSuccessful = false;
  215.                 }
  216.                
  217.                
  218.                 try {
  219.                     // Stops if the compile is disabled
  220.                     if(zenParsedFile == null || scriptFile.isCompileBlocked() || !loadSuccessful) {
  221.                         if (!isLinter)
  222.                             CRT_LOADING_SCRIPT_POST_EVENT_LIST.publish(new CrTLoadingScriptEventPost(filename));
  223.                         continue;
  224.                     }
  225.                     compileScripts(className, Collections.singletonList(zenParsedFile), environmentGlobal, scriptFile.isDebugEnabled() || DEBUG);
  226.                    
  227.                     // stops if the execution is disabled
  228.                     if(scriptFile.isExecutionBlocked() || isSyntaxCommand || isLinter) {
  229.                         if (!isLinter)
  230.                             CRT_LOADING_SCRIPT_POST_EVENT_LIST.publish(new CrTLoadingScriptEventPost(filename));
  231.                         continue;
  232.                     }
  233.                    
  234.                     ZenModule module = new ZenModule(classes, CraftTweakerAPI.class.getClassLoader());
  235.                     Runnable runnable = module.getMain();
  236.                     if(runnable != null)
  237.                         runnable.run();
  238.                 } catch(Throwable ex) {
  239.                     CraftTweakerAPI.logError("[" + loaderName + "]: Error executing " + scriptFile + ": " + ex.getMessage(), ex);
  240.                 }
  241.                
  242.                 if(!isLinter)
  243.                     CRT_LOADING_SCRIPT_POST_EVENT_LIST.publish(new CrTLoadingScriptEventPost(filename));
  244.                 //CraftTweakerAPI.logDefault("Completed file: " + filename +" in: " + (System.currentTimeMillis() - time) + "ms");
  245.             }
  246.            
  247.         }
  248.        
  249.         if(parseExceptions != null) {
  250.             CrtStoringErrorLogger logger = (CrtStoringErrorLogger) GlobalRegistry.getErrors();
  251.             parseExceptions.addAll(logger.getErrors());
  252.            
  253.             CrTGlobalEnvironment global = (CrTGlobalEnvironment) environmentGlobal;
  254.             parseExceptions.addAll(global.getErrors());
  255.         }
  256.        
  257.        
  258.         loader.setLoaderStage(loadSuccessful ? ScriptLoader.LoaderStage.LOADED_SUCCESSFUL : ScriptLoader.LoaderStage.ERROR);
  259.         if(!isLinter)
  260.             CRT_LOADING_FINISHED_EVENT_EVENT_LIST.publish(new CrTLoaderLoadingEvent.Finished(loader, networkSide, isSyntaxCommand));
  261.         CraftTweakerAPI.logDefault("Completed script loading in: " + (System.currentTimeMillis() - totalTime) + "ms");
  262.         return loadSuccessful;
  263.     }
  264.    
  265.     protected List<ScriptFile> collectScriptFiles(boolean isSyntaxCommand) {
  266.         List<ScriptFile> fileList = new ArrayList<>();
  267.         HashSet<String> collected = new HashSet<>();
  268.        
  269.         // Collecting all scripts
  270.         Iterator<IScriptIterator> scripts = scriptProvider.getScripts();
  271.         while(scripts.hasNext()) {
  272.             IScriptIterator script = scripts.next();
  273.            
  274.             if(!collected.contains(script.getGroupName())) {
  275.                 collected.add(script.getGroupName());
  276.                
  277.                 while(script.next()) {
  278.                     fileList.add(new ScriptFile(this, script.copyCurrent(), isSyntaxCommand));
  279.                 }
  280.             }
  281.         }
  282.         return fileList;
  283.     }
  284.    
  285.     private String getTweakerDescriptor(String loaderName) {
  286.         return "[" + loaderName + " | " + networkSide + "]";
  287.     }
  288.    
  289.     @Override
  290.     public List<IAction> getActions() {
  291.         return actions;
  292.     }
  293.    
  294.     @Override
  295.     public void enableDebug() {
  296.         DEBUG = true;
  297.     }
  298.    
  299.     @Override
  300.     public PreprocessorManager getPreprocessorManager() {
  301.         return preprocessorManager;
  302.     }
  303.    
  304.     public NetworkSide getNetworkSide() {
  305.         return networkSide;
  306.     }
  307.    
  308.     public void setNetworkSide(NetworkSide networkSide) {
  309.         this.networkSide = networkSide;
  310.     }
  311.    
  312.     public void registerLoadStartedEvent(IEventHandler<CrTLoaderLoadingEvent.Started> eventHandler) {
  313.         CRT_LOADING_STARTED_EVENT_EVENT_LIST.add(eventHandler);
  314.     }
  315.    
  316.     public void registerLoadFinishedEvent(IEventHandler<CrTLoaderLoadingEvent.Finished> eventHandler) {
  317.         CRT_LOADING_FINISHED_EVENT_EVENT_LIST.add(eventHandler);
  318.     }
  319.    
  320.     public void registerLoadAbortedEvent(IEventHandler<CrTLoaderLoadingEvent.Aborted> eventHandler) {
  321.         CRT_LOADING_ABORTED_EVENT_EVENT_LIST.add(eventHandler);
  322.     }
  323.    
  324.     public void registerScriptLoadPreEvent(IEventHandler<CrTScriptLoadingEvent.Pre> eventHandler) {
  325.         CRT_LOADING_SCRIPT_PRE_EVENT_LIST.add(eventHandler);
  326.     }
  327.    
  328.     public void registerScriptLoadPostEvent(IEventHandler<CrTScriptLoadingEvent.Post> eventHandler) {
  329.         CRT_LOADING_SCRIPT_POST_EVENT_LIST.add(eventHandler);
  330.     }
  331.    
  332.     private ScriptLoader getLoader(String... names) {
  333.         for(ScriptLoader loader : loaders) {
  334.             if(loader.canExecute(names))
  335.                 return loader;
  336.         }
  337.         return null;
  338.     }
  339.    
  340.     private ScriptLoader getOrAddLoader(String... names) {
  341.         ScriptLoader loader = getLoader(names);
  342.         if(loader != null)
  343.             return loader;
  344.         return getOrCreateLoader(names);
  345.     }
  346.    
  347.     @Override
  348.     public List<ScriptLoader> getLoaders() {
  349.         return loaders;
  350.     }
  351.    
  352.     /**
  353.      * Adds a loader, merges with other Lists if possible
  354.      */
  355.     @Override
  356.     public ScriptLoader getOrCreateLoader(String... nameAndAliases) {
  357.         Iterator<ScriptLoader> it = loaders.iterator();
  358.         ScriptLoader mergeLoader = null;
  359.        
  360.         while(it.hasNext()) {
  361.             ScriptLoader loader = it.next();
  362.             if(loader.canExecute(nameAndAliases)) {
  363.                 loader.addAliases(nameAndAliases);
  364.                
  365.                 if(mergeLoader == null) {
  366.                     mergeLoader = loader;
  367.                 } else {
  368.                     mergeLoader.addAliases(loader.getNames().toArray(new String[0]));
  369.                     mergeLoader.setMainName(loader.getMainName());
  370.                     if(loader.getLoaderStage() != ScriptLoader.LoaderStage.NOT_LOADED && loader.getLoaderStage() != ScriptLoader.LoaderStage.INVALIDATED)
  371.                         mergeLoader.setLoaderStage(loader.getLoaderStage());
  372.                     loader.setLoaderStage(ScriptLoader.LoaderStage.INVALIDATED);
  373.                     it.remove();
  374.                 }
  375.             }
  376.         }
  377.        
  378.         if(mergeLoader == null) {
  379.             mergeLoader = new ScriptLoader(nameAndAliases);
  380.             loaders.add(mergeLoader);
  381.         }
  382.        
  383.         CraftTweakerAPI.logDefault("Current loaders after merging: " + loaders);
  384.         return mergeLoader;
  385.     }
  386.    
  387.     public void resetLoaderStats() {
  388.         for(ScriptLoader loader : loaders) {
  389.             loader.setLoaderStage(ScriptLoader.LoaderStage.NOT_LOADED);
  390.         }
  391.     }
  392. }
  393.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement