Пример #1
0
        public C2Addon ReadEdittimeJs(string source)
        {
            c2addon = new C2Addon();
            var     parser  = new JavaScriptParser(source);
            var     program = parser.ParseProgram();
            var     json    = program.ToJsonString();
            dynamic ast     = JObject.Parse(json);

            return(TraverseJavascriptTree(ast));
        }
Пример #2
0
        public static string GenerateBehaviorJs(C2Addon addon)
        {
            //
            var id      = addon.Properties["id"];
            var name    = addon.Properties["name"];
            var author  = addon.Properties["author"];
            var onlyOne = addon.Properties["flags"].Contains("bf_onlyone").ToString().ToLower();

            var propList = string.Join(",\n                        ", addon.PluginProperties.Select(GeneratePluginProperty));

            var template = $@"""use strict"";
{{
            const BEHAVIOR_ID = ""{id}"";	
	        const BEHAVIOR_VERSION = ""1.0.0.0"";
	        const BEHAVIOR_CATEGORY = ""other"";
	        
	        const BEHAVIOR_CLASS = SDK.Behaviors.{id} = class {name}Behavior extends SDK.IBehaviorBase
	        {{
	            constructor()
	            {{
			        super(BEHAVIOR_ID);
			        
			        SDK.Lang.PushContext(""behaviors."" + BEHAVIOR_ID.toLowerCase());
			        
			        this._info.SetName(lang("".name""));
			        this._info.SetDescription(lang("".description""));
			        this._info.SetVersion(BEHAVIOR_VERSION);
			        this._info.SetCategory(BEHAVIOR_CATEGORY);
			        this._info.SetAuthor(""{author}"");
			        this._info.SetHelpUrl(lang("".help-url""));
			        this._info.SetIsOnlyOneAllowed({onlyOne});

                    this._info.SetSupportedRuntimes([""c3""]);
			
                    SDK.Lang.PushContext("".properties"");
	
                    this._info.SetProperties([
                        {propList}
                    ]);
			
                    SDK.Lang.PopContext(); //.properties
                    SDK.Lang.PopContext();
                }}
            }};
	
            PLUGIN_CLASS.Register(PLUGIN_ID, PLUGIN_CLASS);
 }}";

            return(template);
        }
Пример #3
0
        public C2Addon Parse(string json)
        {
            var     c2addon = new C2Addon();
            dynamic data    = JObject.Parse(json);

            //settings
            var settings = data["settings"];

            foreach (JProperty prop in settings)
            {
                //handle array
                if (prop.Name == "flags")
                {
                    var sb = new StringBuilder();
                    foreach (var val in prop.Value)
                    {
                        sb.Append($" {val} ");
                    }
                    c2addon.Properties.Add(prop.Name, sb.ToString());
                    continue;
                }

                c2addon.Properties.Add(prop.Name, prop.Value.ToString());
            }

            //properties
            var props = data["properties"];

            foreach (var p in props)
            {
                var property = new C2Property();

                property.Type        = p["flags"].ToString();
                property.Name        = p["key"].ToString();
                property.Value       = p["initial_str"]?.ToString() ?? string.Empty;
                property.Description = p["description"].ToString();
                var flags = p["params"];
                var fList = new List <string>();
                foreach (var flag in flags)
                {
                    fList.Add(flag);
                }
                property.Params   = string.Join("|", fList);
                property.Readonly = p["read_only"] != null ? p["read_only"].ToString().ToLower() : "false";
            }

            //actions
            var actions = data["actions"];

            c2addon.Actions = new List <C2Ace>();
            foreach (JObject act in actions)
            {
                var ace = new C2Ace
                {
                    Id            = act["id"].ToString(),
                    ListName      = act["list_name"].ToString(),
                    Category      = act["category"].ToString(),
                    DisplayString = act["display_string"].ToString(),
                    Description   = act["description"].ToString(),
                    ScriptName    = act["script_name"].ToString()
                };

                //get flags
                var sb = new StringBuilder();
                foreach (var val in act["flags"])
                {
                    sb.Append($" {val} ");
                }
                ace.Flags = sb.ToString();

                //params
                foreach (var param in act["params"])
                {
                    var aceParam = new C2AceParam
                    {
                        Text         = param["name"]?.ToString(),
                        Description  = param["description"]?.ToString(),
                        DefaultValue = param["initial"]?.ToString(),
                        Script       = param["caller"]?.ToString()
                    };

                    if (param["caller"]?.ToString() == "AddComboParam")
                    {
                        aceParam.ComboItems = new List <string>();
                        foreach (var val in param["options"])
                        {
                            aceParam.ComboItems.Add(val["text"].ToString());
                        }
                    }

                    ace.Params.Add(aceParam);
                    c2addon.Actions.Add(ace);
                }
            }

            //conditions
            var conditions = data["conditions"];

            c2addon.Conditions = new List <C2Ace>();
            foreach (JObject cnd in conditions)
            {
                var ace = new C2Ace
                {
                    Id            = cnd["id"].ToString(),
                    ListName      = cnd["list_name"].ToString(),
                    Category      = cnd["category"].ToString(),
                    DisplayString = cnd["display_string"].ToString(),
                    Description   = cnd["description"].ToString(),
                    ScriptName    = cnd["script_name"].ToString()
                };

                //get flags
                var sb = new StringBuilder();
                foreach (var val in cnd["flags"])
                {
                    sb.Append($" {val} ");
                }
                ace.Flags = sb.ToString();

                //params
                foreach (var param in cnd["params"])
                {
                    var aceParam = new C2AceParam
                    {
                        Text         = param["name"]?.ToString(),
                        Description  = param["description"]?.ToString(),
                        DefaultValue = param["initial"]?.ToString(),
                        Script       = param["caller"]?.ToString()
                    };

                    if (param["caller"]?.ToString() == "AddComboParam")
                    {
                        aceParam.ComboItems = new List <string>();
                        foreach (var val in param["options"])
                        {
                            aceParam.ComboItems.Add(val["text"].ToString());
                        }
                    }

                    ace.Params.Add(aceParam);
                }
                c2addon.Conditions.Add(ace);
            }

            //expressions
            var expressions = data["expressions"];

            c2addon.Expressions = new List <C2Ace>();
            foreach (JObject exp in expressions)
            {
                var ace = new C2Ace
                {
                    Id          = exp["id"].ToString(),
                    ListName    = exp["list_name"].ToString(),
                    Category    = exp["category"].ToString(),
                    Description = exp["description"].ToString(),
                    ScriptName  = exp["expression_name"].ToString(),
                };

                //get flags
                var sb = new StringBuilder();
                foreach (var val in exp["flags"])
                {
                    sb.Append($" {val} ");
                }
                ace.Flags = sb.ToString();

                //params
                foreach (var param in exp["params"])
                {
                    var aceParam = new C2AceParam
                    {
                        Text         = param["name"]?.ToString(),
                        Description  = param["description"]?.ToString(),
                        DefaultValue = param["initial"]?.ToString(),
                        Script       = param["caller"]?.ToString()
                    };

                    if (param["caller"]?.ToString() == "AddComboParam")
                    {
                        aceParam.ComboItems = new List <string>();
                        foreach (var val in param["options"])
                        {
                            aceParam.ComboItems.Add(val["text"].ToString());
                        }
                    }

                    ace.Params.Add(aceParam);
                }

                c2addon.Expressions.Add(ace);
            }

            return(c2addon);
        }
Пример #4
0
        public async Task <C3Addon> Import2Addon(string path)
        {
            WindowManager.ShowLoadingOverlay(true);

            try
            {
                C2Addon c2addon = null;
                C3Addon c3addon = null;

                await Task.Run(() =>
                {
                    var tmpPath = OptionsManager.CurrentOptions.DataPath + "\\tmp_c2";
                    if (Directory.Exists(tmpPath))
                    {
                        Directory.Delete(tmpPath, true);
                    }

                    //unzip c3addon to temp location
                    ZipFile.ExtractToDirectory(path, tmpPath);

                    var edittimefile = Directory.GetFiles(tmpPath, "edittime.js", SearchOption.AllDirectories).FirstOrDefault();
                    var runtimefile  = Directory.GetFiles(tmpPath, "runtime.js", SearchOption.AllDirectories).FirstOrDefault();
                    var effectXml    = Directory.GetFiles(tmpPath, "*.xml", SearchOption.AllDirectories).FirstOrDefault(x => !x.Contains("info.xml"));
                    var effectCode   = Directory.GetFiles(tmpPath, "*.fx", SearchOption.AllDirectories).FirstOrDefault();

                    LogManager.AddImportLogMessage($"edittime.js => {edittimefile}");

                    if (edittimefile != null)
                    {
                        var source = File.ReadAllText(edittimefile);

                        //try to parse file using https://github.com/WebCreationClub/construct-addon-parser
                        try
                        {
                            if (!OptionsManager.CurrentOptions.UseC2ParserService)
                            {
                                throw new Exception("C2 parsing service is no enabled");
                            }
                            c2addon = C2ParsingService.Insatnce.Execute(source);
                        }
                        //if online parse fails fallback to walkign ast tree
                        catch (Exception ex)
                        {
                            LogManager.AddErrorLog(ex);
                            LogManager.AddImportLogMessage(
                                $"C2 Pasring Service Failed => {ex.Message} \nFalling back to Walking Edittime.js AST");

                            c2addon = C2AddonParser.Insatnce.ReadEdittimeJs(source);
                        }

                        LogManager.AddImportLogMessage(
                            $"C2 Parsed Model => \n\n\n {JsonConvert.SerializeObject(c2addon, Formatting.Indented)}");
                        c3addon = C2AddonConverter.Insatnce.ConvertToC3(c2addon);
                        //todo generate properties/category
                        var runtime = !string.IsNullOrWhiteSpace(runtimefile)
                            ? File.ReadAllText(runtimefile)
                            : string.Empty;
                        c3addon.C2RunTime = runtime;
                    }
                    else
                    {
                        //check for effect
                        LogManager.AddImportLogMessage($"effect xml => {effectXml}");
                        if (!string.IsNullOrWhiteSpace(effectXml) && !string.IsNullOrWhiteSpace(effectCode))
                        {
                            try
                            {
                                var xml  = File.ReadAllText(effectXml);
                                var code = File.ReadAllText(effectCode);

                                c3addon = C2EffectConverter.Insatnce.ConvertEffect(xml, code);
                            }
                            catch (Exception ex)
                            {
                                LogManager.AddErrorLog(ex);
                                throw;
                            }
                        }
                    }
                });

                if (c3addon != null)
                {
                    return(c3addon);
                }

                LogManager.AddImportLogMessage($"ERROR => edittime.js not found => null");
                throw new Exception("edittime.js not found");
            }
            catch (Exception ex)
            {
                LogManager.AddErrorLog(ex);
                LogManager.AddImportLogMessage($"ERROR => \n{ex.Message}");
                LogManager.AddImportLogMessage($"STACKTRACE => \n{ex.StackTrace}");
                return(null);
            }
            finally
            {
                var logData = string.Join(Environment.NewLine, LogManager.ImportLog);
                File.WriteAllText(Path.Combine(OptionsManager.CurrentOptions.DataPath, "import.log"), logData);
                LogManager.ImportLog.Clear();
                WindowManager.ShowLoadingOverlay(false);
            }
        }
Пример #5
0
        public static string GeneratePluginJs(C2Addon addon)
        {
            var id            = addon.Properties["id"];
            var name          = addon.Properties["name"];
            var author        = addon.Properties["author"];
            var singleglobal  = addon.Properties["flags"].Contains("pf_singleglobal").ToString().ToLower();
            var pluginType    = addon.Properties["type"];
            var hasImage      = addon.Properties["flags"].Contains("pf_texture").ToString().ToLower();
            var isTiled       = addon.Properties["flags"].Contains("pf_tiling").ToString().ToLower();
            var acePos        = addon.Properties["flags"].Contains("pf_position_aces") ? "\n                    this._info.AddCommonPositionACEs();" : string.Empty;
            var aceSize       = addon.Properties["flags"].Contains("pf_size_aces") ? "\n                    this._info.AddCommonSizeACEs();" : string.Empty;
            var aceApp        = addon.Properties["flags"].Contains("pf_appearance_aces") ? "\n                    this._info.AddCommonAppearanceACEs();" : string.Empty;
            var aceZor        = addon.Properties["flags"].Contains("pf_zorder_aces") ? "\n                    this._info.AddCommonZOrderACEs();" : string.Empty;
            var aceAngle      = addon.Properties["flags"].Contains("pf_angle_aces") ? "\n                    this._info.AddCommonAngleACEs();" : string.Empty;
            var effectAllowed = addon.Properties["flags"].Contains("pf_effects").ToString().ToLower();
            var predraw       = addon.Properties["flags"].Contains("pf_predraw").ToString().ToLower();
            var nosize        = (!addon.Properties["flags"].Contains("pf_nosize")).ToString().ToLower();

            var propList = string.Join(",\n                        ", addon.PluginProperties.Select(GeneratePluginProperty));

            var rotate = addon.Properties.ContainsKey("rotatable") ? addon.Properties["rotatable"].ToLower() : "false";

            var template = $@"""use strict"";
{{
            const PLUGIN_ID = ""{id}"";	
            const PLUGIN_VERSION = ""1.0.0.0"";
            const PLUGIN_CATEGORY = ""other"";
	
            const PLUGIN_CLASS = SDK.Plugins.{id} = class {name}Plugin extends SDK.IPluginBase
            {{
                constructor()
                {{
                    super(PLUGIN_ID);
			
                    SDK.Lang.PushContext(""plugins."" + PLUGIN_ID.toLowerCase());
			
                    this._info.SetName(lang("".name""));
                    this._info.SetDescription(lang("".description""));
                    this._info.SetVersion(PLUGIN_VERSION);
                    this._info.SetCategory(PLUGIN_CATEGORY);
                    this._info.SetAuthor(""{author}"");
                    this._info.SetHelpUrl(lang("".help-url""));
                    this._info.SetIsSingleGlobal({singleglobal});
                    this._info.SetPluginType(""{pluginType}"");
                    this._info.SetIsResizable({nosize});			    // allow to be resized
			        this._info.SetIsRotatable({rotate});	            // allow to be rotated
			        this._info.SetHasImage({hasImage});
			        this._info.SetSupportsEffects({effectAllowed});		// allow effects
			        this._info.SetMustPreDraw({predraw});
                    this._info.SetIsTiled({isTiled});{acePos}{aceAngle}{aceApp}{aceSize}{aceZor}

                    this._info.SetSupportedRuntimes([""c3""]);
			
                    SDK.Lang.PushContext("".properties"");
	
                    this._info.SetProperties([
                        {propList}
                    ]);
			
                    SDK.Lang.PopContext(); //.properties
                    SDK.Lang.PopContext();
                }}
            }};
	
            PLUGIN_CLASS.Register(PLUGIN_ID, PLUGIN_CLASS);
 }}";

            return(template);
        }
Пример #6
0
        public C3Addon ConvertToC3(C2Addon c2addon)
        {
            if (c2addon == null)
            {
                throw new NullReferenceException("C2ADDON file is null");
            }
            if (c2addon.Type == "Effect")
            {
                throw new Exception("C2 Effect Currently not supported for import");                          //todo: need to develop this
            }
            //add fall back for not being able to parse type
            if (c2addon.Type == null)
            {
                c2addon.Properties.TryGetValue("type", out var type);

                switch (type)
                {
                case "plugin":
                    c2addon.Type = "Plugin";
                    break;

                case "behavior":
                    c2addon.Type = "Behavior";
                    break;

                case "effect":
                    throw new Exception("C2 Effect Currently not supported for import");

                default:
                    c2addon.Type = "Plugin";
                    break;
                }
            }

            var c3addon = new C3Addon
            {
                Name            = c2addon.Properties["name"],
                Class           = c2addon.Properties["name"],
                Author          = c2addon.Properties["author"],
                AddonId         = c2addon.Properties["id"],
                Description     = c2addon.Properties["description"],
                AddonCategory   = c2addon.Properties["category"],
                Effect          = new Effect(),
                IconXml         = ResourceReader.Insatnce.GetResourceText("c3IDE.Templates.Files.icon.svg"),
                CreateDate      = DateTime.Now,
                LastModified    = DateTime.Now,
                MajorVersion    = 1,
                MinorVersion    = 0,
                RevisionVersion = 0,
                BuildVersion    = 0
            };

            //add version
            PluginType pluginType = PluginType.SingleGlobalPlugin;

            switch (c2addon.Type)
            {
            case "Plugin":
            {
                if (c2addon.Properties["type"] == "object")
                {
                    pluginType = PluginType.SingleGlobalPlugin; break;
                }
                pluginType = PluginType.DrawingPlugin; break;
            }

            case "Behavior": pluginType = PluginType.Behavior; break;

            case "Effect": pluginType = PluginType.Effect; break;
            }
            c3addon.Type = pluginType;

            //get templates based on type
            c3addon.Template = TemplateFactory.Insatnce.CreateTemplate(c3addon.Type);

            //compile other files
            AddonManager.CompileTemplates(c3addon);

            //add actions
            c3addon.Actions = new Dictionary <string, Models.Action>();
            foreach (var c2Action in c2addon.Actions)
            {
                C2AcesToAction(c3addon, c2Action);
            }

            //conditions
            c3addon.Conditions = new Dictionary <string, Models.Condition>();
            foreach (var c2Condition in c2addon.Conditions)
            {
                C2AcesToCondition(c3addon, c2Condition);
            }

            //expression
            c3addon.Expressions = new Dictionary <string, Models.Expression>();
            foreach (var c2Expression in c2addon.Expressions)
            {
                C2AceToExpression(c3addon, c2Expression);
            }

            //third party files
            if (c2addon.Properties.ContainsKey("dependency"))
            {
                //todo: handle third party files
            }

            //handle plugin properties

            //update edit time plugin
            switch (c3addon.Type)
            {
            case PluginType.SingleGlobalPlugin:
            case PluginType.DrawingPlugin:
                c3addon.PluginEditTime = C2TemplateHelper.GeneratePluginJs(c2addon);
                break;

            case PluginType.Behavior:
                c3addon.PluginEditTime = C2TemplateHelper.GenerateBehaviorJs(c2addon);
                break;

            case PluginType.Effect:
                throw new NotImplementedException("effects are not implement yet");

            default:
                throw new ArgumentOutOfRangeException();
            }

            //use c2addon to generate text for properties

            return(c3addon);
        }