public async Task <ScriptDef> GetScriptDef(string id) { ScriptDef res = new(); var op = _master.AddSynchronousOp(() => { var pd = _master.GetScriptDef(id); if (pd is null) { throw HttpException.NotFound(); } res = new ScriptDef(pd); }); await op.WaitAsync(); return(res); }
private static void LoadScriptBlock(Level level, ScriptDef targetSD, XmlNode node, ScriptBlock root, string firstChildName = "") { if (node == null || root == null) { return; } var child = node.FirstChild; if (child == null) { return; } do { if (!firstChildName.Equals("")) { if (!child.Name.Equals(firstChildName, StringComparison.InvariantCultureIgnoreCase)) { Log.WriteInfo("Attention ! Impossible d'ajouter le scriptBlock : " + child.Name + " alors que le scriptBlock obligatoire est : " + firstChildName); continue; } } ScriptBlock scriptBlock = null; switch (child.Name.ToLower()) { case "action": { var a = child.Attributes?["a"]; if (a == null) throw new Exception(" le scriptBlock <action> ne contient pas d'action \"a\" !"); var p = child.Attributes?["p"]; if (p == null) throw new Exception(" le scriptBlock <action> ne contient pas de paramètres ! \"p\" "); var parameters = new List<string>(); var i = 1; do { parameters.Add(p.Value); ++i; } while ((p = child.Attributes?["p" + i]) != null); scriptBlock = new ScriptAction(level, a.Value, parameters); } break; case "update": { var delayA = child.Attributes?["delay"]; if (delayA == null) throw new Exception(" le scriptBlock <update> ne contient pas de delay"); double delay = 0.0; if (delayA.Value.Equals("$FRAME_RATE")) { delay = 1.0 / 60.0; } else { if (!double.TryParse(delayA.Value, out delay)) throw new Exception(" le scriptBlock <update> ne contient pas de delay valide !"); if (delay <= 0) throw new Exception(" le scriptBlock <update> ne contient pas un delay valide ! Il est plus petit ou égal à 0 !"); } scriptBlock = new ScriptUpdate(delay); LoadScriptBlock(level, targetSD, child, scriptBlock); } break; case "condition": { var varRefA = child.Attributes?["ref"]; var valueConditionA = child.Attributes?["value"]; if (varRefA == null || valueConditionA == null) throw new Exception(" le scriptBlock <condition> ne contient pas la référence vers la variable ou sa condition \"ref\" ou \"value\" !"); if (!targetSD.Variables.ContainsKey(varRefA.Value)) throw new Exception(" le scriptBlock <condition> utilise la variable : " + varRefA.Value + " alors qu'elle n'est pas définie dans <variables> !"); var variable = targetSD.Variables[varRefA.Value]; if (variable is int) { if (!int.TryParse(valueConditionA.Value, out var condition)) { throw new Exception(" dans le scriptBlock <condition>, la condition utilisée ne peut pas être convertie en nombre (int) !"); } scriptBlock = new ScriptCondition<int>(varRefA.Value, condition); } else if (variable is bool) { if (!bool.TryParse(valueConditionA.Value, out var condition)) { throw new Exception(" dans le scriptBlock <condition>, la condition utilisée ne peut pas être convertie en booléen (bool) !"); } scriptBlock = new ScriptCondition<bool>(varRefA.Value, condition); } else throw new Exception(" le scriptBlock <condition> utilise une variable dont le type est inconnu !"); LoadScriptBlock(level, targetSD, child, scriptBlock); } break; case "collision": { var dirSide = child.Attributes?["side"]; var typeRef = child.Attributes?["typeRef"]; if (dirSide == null || typeRef == null) throw new Exception(" le scriptBlock <collision> ne contient pas la direction \"side\" ou la référence \"typeRef\" !"); var sides = new List<PhysicsBody.CollisionSide>(); var rawSides = dirSide.Value.Split('|'); foreach (var rawSide in rawSides) { if (!Enum.TryParse<PhysicsBody.CollisionSide>(rawSide, out var side)) throw new Exception(" le scriptBlock <collision> contient une erreur ! Impossible de convertir : " + dirSide.Value + " en direction !"); sides.Add(side); } scriptBlock = new ScriptCollisionEvent(sides, typeRef.Value); LoadScriptBlock(level, targetSD, child, scriptBlock); } break; case "key": { var codeA = child.Attributes?["code"]; var justPressedA = child.Attributes?["justPressed"]; var upA = child.Attributes?["up"]; if (codeA == null) throw new Exception(" le scriptBlock <key> ne contient pas la touche \"code\""); if (!Enum.TryParse<Keyboard.Key>(codeA.Value, true, out var key)) { throw new Exception(" le scriptBlock <key> contient une touche qui n'existe pas ! : " + codeA.Value); } bool justPressed = false, up = false; if (justPressedA != null) { if (!bool.TryParse(justPressedA.Value, out justPressed)) throw new Exception(" le scriptBlock <key> contient des erreurs ! Impossible de convertir : " + justPressedA.Value + " en valeur booléenne !"); } if (upA != null) { if (!bool.TryParse(upA.Value, out up)) throw new Exception(" le scriptBlock <key> contient des erreurs ! Impossible de convertir : " + upA.Value + " en valeur booléenne !"); } scriptBlock = new ScriptInput(key, justPressed, up); LoadScriptBlock(level, targetSD, child, scriptBlock); } break; } if (scriptBlock == null) throw new Exception(" le script contient un scriptBlock inconnu !"); root.AddChild(scriptBlock); } while ((child = child.NextSibling) != null); }
public static Level LoadLevel(Game game, FileInfo levelFile) { if (!levelFile.Exists) throw new Exception("Le niveau : " + levelFile + " n'existe pas !"); const string error = "Le niveau présente des erreurs Json !"; using (var reader = File.OpenText(levelFile.ToString())) { var root = JToken.ReadFrom(new JsonTextReader(reader)) as JObject; if(root == null) throw new Exception(error); if (root.TryGetValue("levelName", out var levelName)) { var level = new Level(levelName.ToString(), levelFile, new Vector2f(game.GetWindowSize().X, game.GetWindowSize().Y)); Log.WriteInfo("Chargement du niveau : " + level.Name); /* * Listes des scripts a charger pour le niveau * Ex : "loadScripts":[ * "player.script", * "sprite.script" * ], */ if (root.TryGetValue("loadScripts", out var loadScripts)) { foreach (var loadScript in loadScripts) { Log.WriteInfo("Chargement du script : " + loadScript); var scriptDef = ScriptManager.LoadScriptDef(level, new FileInfo(@"Resources/scripts/" + loadScript)); if (scriptDef.HasValue) { // Chargement des textures non dynamiques // foreach (var scriptState in scriptDef.Value.ScriptStates) { foreach (var texture in scriptState.Value.Textures) { if (!level.LoadTextures.ContainsKey(texture.Value.ToString())) { if(!texture.Value.ToString().Equals("$")) level.LoadTextures.Add(texture.Value.ToString(), new Texture(texture.Value.ToString())); } } } level.AddScriptDef(scriptDef.Value); } else throw new Exception("Erreur lors du chargement du niveau ! Un script contient des erreurs !"); } } else throw new Exception(error + " Il ne contient pas les scripts à charger ! (loadScripts)"); /* * Listes des scripts chargé à ajouter au niveau * Ex : "scripts":[ * { * "ref":"physicsSprite", * "pos":{ * "x":279, * "y":106 * }, * "states":[ * { * "ref":"default", * "width":50, * "height":50, * "textures":[ * { * "ref":"default", * "path":"Resources\\levelObjects\\blocks\\brick\\Brick Blue.png" * } * ] * } * ] * }, * ] */ if (root.TryGetValue("scripts", out var scripts)) { foreach (var script in scripts.ToArray()) { var reference = script["ref"]; var pos = script["pos"]; var states = script["states"]; if(reference == null || pos == null || states == null) throw new Exception(error + " Un script ne contient pas sa référence \"ref\" ou sa position \"pos\" ou ses states \"states\" !"); if (!level.ScriptDefs.ContainsKey((string)reference)) { throw new Exception("Le niveau ne contient pas le script : " + (string)reference); } var scriptDef = new ScriptDef(level.ScriptDefs[(string)reference]); var xA = (string)pos["x"]; var yA = (string)pos["y"]; if(xA == null || yA == null) throw new Exception(error + " Un script ne contient pas une position correcte !"); if(!int.TryParse(xA, out var x) || !int.TryParse(yA, out var y)) { throw new Exception(error + " Impossible de convertir la position en nombre(int) !"); } foreach (var state in states.ToArray()) { var refState = state["ref"]; if(refState == null) throw new Exception(error + " Le script : " + reference + " contient des erreurs dans la bloc \"states\", la référence est null !"); if(!scriptDef.ScriptStates.ContainsKey((string)refState)) throw new Exception(error + " Le script : " + reference + " ne contient pas le state : " + refState + " !"); var scriptState = scriptDef.ScriptStates[(string) refState]; if (scriptState.Width == ScriptState.DynamicSize) { var width = state["width"]; if(width == null) throw new Exception(error + " Le script : " + reference + " a besoin d'une largeur (width) !"); if(!int.TryParse((string)width, out var widthValue)) throw new Exception(error + " Le script : " + reference + " a besoin d'une largeur (width) (erreur de conversion en int) !"); scriptState.Width = widthValue; } if (scriptState.Height == ScriptState.DynamicSize) { var height = state["height"]; if (height == null) throw new Exception(error + " Le script : " + reference + " a besoin d'une hauteur (height) !"); if (!int.TryParse((string)height, out var heightValue)) throw new Exception(error + " Le script : " + reference + " a besoin d'une hauteur (height) (erreur de conversion en int) !"); scriptState.Height = heightValue; } var textures = state["textures"]; foreach (var textureJson in textures.ToArray()) { var refTexture = textureJson["ref"]; var path = textureJson["path"]; if(refTexture == null || path == null) throw new Exception(error + " Le script : " + reference + " contient des textures dynamiques invalides ! La référence ou le chemin est null !"); if(!File.Exists((string)path)) throw new Exception(error + " La texture dynamique : " + path + " n'existe pas !"); if(!scriptState.Textures.ContainsKey((string) refTexture)) throw new Exception(error + " Le script : " + reference + " ne contient pas la texture dynamique : " + refTexture + " !"); if(!scriptState.Textures[(string) refTexture].ToString().Equals("$")) throw new Exception(error + " Le script : " + reference + " contient la texture dynamique : " + refTexture + " mais n'est pas une texture dynamique !"); if(!level.LoadTextures.ContainsKey((string)path)) level.LoadTextures.Add((string) path, new Texture((string) path)); scriptState.Textures[(string) refTexture] = new FileInfo((string) path); } scriptDef.ScriptStates[(string) refState] = scriptState; } level.AddScript(new Script(new Vector2f(x, y), scriptDef)); } } return level; } else { throw new Exception(error + " Il ne contient pas le nom du niveau !"); } } }
public static ScriptDef? LoadScriptDef(Level level, FileInfo scriptDefFile) { var startError = "Le script : " + scriptDefFile; if (scriptDefFile.Exists) { try { XmlDocument doc = new XmlDocument(); using (var reader = new XmlTextReader(scriptDefFile.ToString())) { doc.Load(reader); var root = doc.FirstChild; if (root == null || !root.Name.Equals("script") || root.Attributes == null) throw new Exception("Le fichier : " + scriptDefFile + " n'est pas un script ou ne contient pas d'attributs dans le root !"); var scriptName = root.Attributes["name"]?.Value; var scriptRef = root.Attributes["ref"]?.Value; if (scriptName == null || scriptRef == null) throw new Exception(startError + " ne contient pas l'attribut name ou ref !"); var scriptDef = new ScriptDef(scriptName, scriptRef); /* * Chargement des variables * Ex : * <variables> * <var ref="isOpen" type="bool" value="false"/> * <var ref="counter" type="int" value="0"/> * </variables> */ var variables = root["variables"]; var childVar = variables?.FirstChild; if (childVar != null) { do { if (childVar.Name.Equals("var")) { var varRefA = childVar.Attributes?["ref"]; var typeA = childVar.Attributes?["type"]; var valueA = childVar.Attributes?["value"]; if (varRefA == null || typeA == null || valueA == null) throw new Exception(startError + " contient une variable avec des erreurs !"); switch (typeA.Value) { case "bool": scriptDef.Variables.Add(varRefA.Value, new bool()); break; case "int": scriptDef.Variables.Add(varRefA.Value, new int()); break; default: throw new Exception(startError + " contient un type de variable non pris en charge !"); } } else throw new Exception(startError + " contient un autre élément qu'une variable dans <variables> !"); } while ((childVar = childVar.NextSibling) != null); } /* * Chargement des states * Ex : <states> * <state ref="default"> * <size width="$" height="$"/> * <textures> * <texture ref="default" path="$"/> * </textures> * * <onLoad> * <action a="setTexture" p="default"/> * </onLoad> * * </state> * </states> */ var states = root["states"]; if (states != null) { var state = states.FirstChild; if (state != null) { do { if (!state.Name.Equals("state")) continue; var reference = state.Attributes?["ref"]; if (reference != null) { var size = state["size"]; if (size != null) { var widthA = size.Attributes?["width"]; var heightA = size.Attributes?["height"]; if (widthA != null && heightA != null) { int width, height; if (widthA.Value.Equals("$")) width = ScriptState.DynamicSize; else if (!int.TryParse(widthA.Value, out width)) throw new Exception(startError + " dans le state : " + reference + " ne contient pas la largeur du script !"); if (heightA.Value.Equals("$")) height = ScriptState.DynamicSize; else if (!int.TryParse(heightA.Value, out height)) throw new Exception(startError + " dans le state : " + reference + " ne contient pas la hauteur du script !"); ScriptState scriptState = new ScriptState(reference.Value, width, height); var textures = state["textures"]; if (textures != null) { foreach (XmlElement texture in textures) { var refTexture = texture.Attributes?["ref"]; var path = texture.Attributes?["path"]; if (refTexture == null || path == null) throw new Exception(startError + " dans le state : " + reference + " a des erreurs dans <textures>, la référence ou le chemin n'est pas bien défini !"); if (!path.Value.Equals("$") && !File.Exists(path.Value)) throw new Exception(startError + " dans le state : " + reference + " contient une texture qui n'existe pas ! Le fichier : " + path.Value + " n'existe pas !"); scriptState.Textures.Add(refTexture.Value, new FileInfo(path.Value)); } } try { LoadScriptBlock(level, scriptDef, state["onLoad"], scriptState.OnLoad); LoadScriptBlock(level, scriptDef, state["onUpdate"], scriptState.OnUpdate, "update"); LoadScriptBlock(level, scriptDef, state["onCollision"], scriptState.OnCollision); LoadScriptBlock(level, scriptDef, state["onKeyPressed"], scriptState.OnKeyPressed, "key"); LoadScriptBlock(level, scriptDef, state["onDeath"], scriptState.OnDeath); } catch (Exception e) { throw new Exception(startError + " dans le state : " + reference.Value + " : " + e.Message); } scriptDef.ScriptStates.Add(scriptState.Ref, scriptState); } else throw new Exception(startError + " dans le state : " + reference.Value + " ne contient pas la largeur ou la hauteur du script !"); } else throw new Exception(startError + " dans le state : " + reference.Value + " ne contient pas la taille <size> !"); } else throw new Exception(startError + " contient une state sans reference !"); } while ((state = state.NextSibling) != null); } else throw new Exception(startError + " ne contient pas de states !"); } else throw new Exception(startError + " ne contient pas de states !"); /* * Chargement des paramètres * Ex : * <settings> * <followCamera value="true"/> * <startState ref="walk"/> * <attachPhysicsBody value="true"/> * <jump jumpMaxCount="40"/> * <gravity value="true"/> * <maxScript value="1"/> * <removeAtPos0 value="true"/> * <dynamic value="true"/> * </settings> */ var settings = root["settings"]; var childSettings = settings?.FirstChild; if (childSettings != null) { do { try { var value = childSettings.Attributes[0].Value; switch (childSettings.Name) { case "followCamera": scriptDef.sFollowCamera = bool.Parse(value); break; case "startState": scriptDef.sStartState = value; break; case "attachPhysicsBody": scriptDef.sAttachPhysicsBody = bool.Parse(value); break; case "jump": scriptDef.sJumpMaxCount = int.Parse(value); break; case "gravity": scriptDef.sGravity = bool.Parse(value); break; case "maxScript": scriptDef.sMaxScript = int.Parse(value); break; case "removeAtPos0": scriptDef.sRemoveAtPos0 = bool.Parse(value); break; case "dynamic": scriptDef.sDynamic = bool.Parse(value); break; default: throw new Exception(startError + " contient un paramètres inconnu ! : " + childSettings.Name); } } catch (Exception e) { throw new Exception(startError + " contient un paramètre avec une valeur inconnue ! + Message : " + e.Message); } } while ((childSettings = childSettings.NextSibling) != null); } return scriptDef; } } catch (Exception e) { throw new Exception(e.Message); } } throw new Exception(startError + " n'existe pas !"); }