public Parameter(string str) { str = Lib.ToLat(str).ToLower().Replace(" ", ""); if(string.IsNullOrWhiteSpace(str)) { ptype = ParType.ANY; tx = string.Empty; par = str; return; } int indx = str.IndexOf(':') + 1; Regex parametr = new Regex(@"\{.+?\}"); Match m = parametr.Match(str, indx); ptype = getParType(str); if (m.Value.Length > 0) { // string like "{result}" with the Brackets par = Regex.Replace(m.Value, @"\{.*?~|\{|\}", ""); tx = str.Substring(indx, m.Index - indx); } else { // result is part of str, recognised as a parameter value int end = str.IndexOf(';'); if (end < indx) end = str.Length; tx = str.Substring(indx, end - indx); par = tx; } }
public ParType getParType(string str) { const string PAR_TYPE = @"\{(s|d|i).*?~"; ParType result = ParType.String; Regex parType = new Regex(PAR_TYPE, RegexOptions.IgnoreCase); Match m = parType.Match(str); if (m.Value == "") return result; switch (m.Value[1]) { case 's': break; case 'd': result = ParType.Double; break; case 'i': result = ParType.Integer; break; } return result; }
public void Load(string name) { if (string.IsNullOrEmpty(name)) { return; } var file = new ContentFile(); List <IPackage> packages; try { file = (ContentFile)_contentManager.GetContentFileFromJson("Stats", name); packages = new List <IPackage>(_contentManager.GetAllLoadedPackages()); } catch (ContentNotFoundException exception) { _logger.Warn(exception.Message); return; } BaseHp = file.GetFloat("Data", "BaseHP", BaseHp); BaseMp = file.GetFloat("Data", "BaseMP", BaseMp); BaseDamage = file.GetFloat("Data", "BaseDamage", BaseDamage); AttackRange = file.GetFloat("Data", "AttackRange", AttackRange); MoveSpeed = file.GetInt("Data", "MoveSpeed", MoveSpeed); Armor = file.GetFloat("Data", "Armor", Armor); SpellBlock = file.GetFloat("Data", "SpellBlock", SpellBlock); BaseStaticHpRegen = file.GetFloat("Data", "BaseStaticHPRegen", BaseStaticHpRegen); BaseStaticMpRegen = file.GetFloat("Data", "BaseStaticMPRegen", BaseStaticMpRegen); AttackDelayOffsetPercent = file.GetFloat("Data", "AttackDelayOffsetPercent", AttackDelayOffsetPercent); AttackDelayCastOffsetPercent = file.GetFloat("Data", "AttackDelayCastOffsetPercent", AttackDelayCastOffsetPercent); HpPerLevel = file.GetFloat("Data", "HPPerLevel", HpPerLevel); MpPerLevel = file.GetFloat("Data", "MPPerLevel", MpPerLevel); DamagePerLevel = file.GetFloat("Data", "DamagePerLevel", DamagePerLevel); ArmorPerLevel = file.GetFloat("Data", "ArmorPerLevel", ArmorPerLevel); SpellBlockPerLevel = file.GetFloat("Data", "SpellBlockPerLevel", SpellBlockPerLevel); HpRegenPerLevel = file.GetFloat("Data", "HPRegenPerLevel", HpRegenPerLevel); MpRegenPerLevel = file.GetFloat("Data", "MPRegenPerLevel", MpRegenPerLevel); AttackSpeedPerLevel = file.GetFloat("Data", "AttackSpeedPerLevel", AttackSpeedPerLevel); IsMelee = file.GetString("Data", "IsMelee", IsMelee ? "true" : "false").Equals("true"); PathfindingCollisionRadius = file.GetFloat("Data", "PathfindingCollisionRadius", PathfindingCollisionRadius); GameplayCollisionRadius = file.GetFloat("Data", "GameplayCollisionRadius", GameplayCollisionRadius); Enum.TryParse <PrimaryAbilityResourceType>(file.GetString("Data", "PARType", ParType.ToString()), out var tempPar); ParType = tempPar; for (var i = 0; i < 4; i++) { SpellNames[i] = file.GetString("Data", $"Spell{i + 1}", SpellNames[i]); } for (var i = 0; i < 4; i++) { SpellsUpLevels[i] = file.GetIntArray("Data", $"SpellsUpLevels{i + 1}", SpellsUpLevels[i]); } MaxLevels = file.GetIntArray("Data", "MaxLevels", MaxLevels); for (var i = 0; i < 8; i++) { ExtraSpells[i] = file.GetString("Data", $"ExtraSpell{i + 1}", ExtraSpells[i]); } for (var i = 0; i < 6; i++) { Passives[i].PassiveNameStr = file.GetString("Data", $"Passive{i + 1}Name", Passives[i].PassiveNameStr); Passives[i].PassiveAbilityName = PassiveData.GetPassiveAbilityNameFromScriptFile(name, packages); Passives[i].PassiveLevels = file.GetMultiInt("Data", $"Passive{i + 1}Level", 6, -1); } }
static bool stop = false; //нужно ли немедленно прекратить выполнение static object RunCmd(string cmd, List <Func> funcs, Dictionary <string, object> vars) //для выполнения очередной команды { //надо помнить, что любая изначально команда, переменная в cmd - это строка, не более if (stop)//если надо останавиться - выходим сразу { return(null); } //чтобы выйти из цикла на любом уровне if (cmd == "break")//оператор break { throw new BreakedExeption("breaked"); } //Вернуть значение из функции if (cmd.StartsWith("return "))//оператор return { throw new ReturnExeption(cmd.Remove(0, 6).Trim()); } //если передана переменная а не команда { ParType p = GetTypeOfParam(cmd); //получаю тип переданной команды if (p != ParType.Method && p != ParType.Invalid) //если это любой тип переменной, возвращаю её значение { //получаю тип параметра и его значение в переменные switch (p) { case ParType.String: return(str); case ParType.Double: return(doub); case ParType.Int: return(integer); case ParType.Boolean: return(boolean); default: return(null); } } } if (cmd.StartsWith("StopAllScripts"))//если это команда для остановки всех скриптов { //новый поток, который ставит stop=true, а когда всё остановлено stop=false Thread th = new Thread(() => { stop = true; while (threads.Count != 0)//ждём, пока есть активные потоки { Thread.Sleep(100); } stop = false; }); th.Start();//запустили поток, и сразу вышли return(null); } if (cmd.StartsWith("if")) //если это конструкция if { List <string> conditions = new List <string>(); //условия List <string> scripts = new List <string>(); //тут все выполняемые части конструкции string ifConstruction = cmd; //конструкция //разбираться будем по частям, удаляя части из конструкции while (ifConstruction != "") //делаем, пока она не пуста { if (ifConstruction[0] != '{') //если это условие или else { if (!ifConstruction.Substring(0, ifConstruction.IndexOf("{")).Contains("(")) //если это else { ifConstruction = ifConstruction.Substring(ifConstruction.IndexOf("{")).Trim(); continue; } string cond = ifConstruction.Substring(0, ifConstruction.IndexOf("{")).Trim(); //берём условие cond = cond.Remove(cond.Length - 1, 1); //убираем ) cond = cond.Substring(cond.IndexOf("(") + 1); //убираем ( conditions.Add(cond); //добавляем это условие ifConstruction = ifConstruction.Substring(ifConstruction.IndexOf("{")).Trim(); //вырезаем всё, что только обработали } else//если подошли к действиям { string sc = ""; //скрипт int countBrackets = 0; //счётчик скобок int i = 0; for (i = 0; ; i++) //в цикле берём команды, находящиеся до следующего условия { if (ifConstruction[i] == '{') { countBrackets++; } else if (ifConstruction[i] == '}') { countBrackets--; } if (countBrackets == 0) { break; } } sc = ifConstruction.Remove(0, 1).Substring(0, i - 1).Trim(); //убираем пробелы ifConstruction = ifConstruction.Substring(i + 1).Trim(); //убираем эту часть scripts.Add(sc); //записываем скрипты } } //разбор завершён if (conditions.Count == scripts.Count)//если у нас не написано else, добавляем пустой скрипт для него { scripts.Add(""); } for (int i = 0; i < conditions.Count; i++) //перебираем все условия по порядку { if ((bool)RunCmd(conditions[i], funcs, vars)) //если условие верно, начинаем выполнение соответствующего скрипты { var cmds = GetCommands(scripts[i]); //получаем команды foreach (var c in cmds) //выполняем по 1 { RunCmd(c, funcs, vars); } return(null);//выходим } } var elseCmds = GetCommands(scripts.Last());//если ни обдно из условий неверно, делаем else и выходим foreach (var c in elseCmds) { RunCmd(c, funcs, vars); } return(null); } if (cmd.StartsWith("while") || cmd.StartsWith("async while")) //цикл while { bool async = cmd.StartsWith("async "); //если асинхронно if (async) { cmd = cmd.Remove(0, 6); //убираем слово "async " } string param = cmd.Remove(0, 5).Trim(); //получаем параметр, убрас слово "while" param = param.Remove(0, 1); //убираем ( param = param.Substring(0, param.IndexOf("{") - 1); //убираем команды param = param.Substring(0, param.LastIndexOf(")")); //убираем последнюю скобку var r = GetPars(param); //получили параметры if (r.Length > 1 || r.Length == 0 || RunCmd(r[0], funcs, vars).GetType() != typeof(bool)) //если недостаточно параметров, если их много, или параметр типа не BOOL { MessageBox.Show("В while не переданы подходящие аргументы"); return(null); } //получаем скрипт string sc = cmd.Substring(cmd.IndexOf("{") + 1, cmd.Length - cmd.IndexOf("{") - 2).Trim(); var cmds = GetCommands(sc); //получаем команды if (async) //если асинхронный { //новый поток для выполнения Thread th = new Thread(() => { var obj = RunCmd(r[0], funcs, vars); //проверяем условие bool b = obj != null ? (bool)obj : false; //преобразуем результат выполнения условия в bool while (b) //пока условие истинно { foreach (var c in cmds) //выполняем команды по 1 { if (c.Trim() == "break" || stop) //если команда стоп { return; } try { RunCmd(c, funcs, vars); } catch (BreakedExeption) { return; } } obj = RunCmd(r[0], funcs, vars); //снова выполняем условие b = obj != null ? (bool)obj : false; //преобразуем } }); th.Start();//запускаем асинхронное выполнение } else { var obj = RunCmd(r[0], funcs, vars); //выполняем условие bool b = obj != null ? (bool)obj : false; //преобразуем в bool while (b) //пока условие истинно { foreach (var c in cmds) //перебираем команда { if (c.Trim() == "break" || stop) //если стоп { return(null); } try { RunCmd(c, funcs, vars); } catch (BreakedExeption) { return(null); } } obj = RunCmd(r[0], funcs, vars); //снова проверяем условие b = obj != null ? (bool)obj : false; //преобразуем в bool } } return(null);//выходим } //если это проверить наличие переменной if (cmd.StartsWith("CheckVar")) { cmd = cmd.Remove(0, 8).Trim(); //убираем "CheckVar" и пробелы cmd = cmd.Remove(0, 1); //убираем ( cmd = cmd.Remove(cmd.Length - 1, 1); //убираем ) string[] parameters = GetPars(cmd); //получаем параметры; if (parameters.Length == 0) //если параметров 0, выходим { return(parameters); } string nameVar = RunCmd(parameters[0], funcs, vars).ToString(); //получаем имя переменной if (parameters.Length == 1) //если дано только имя { return(vars.ContainsKey(nameVar)); } else { string nameOfSpace = RunCmd(parameters[1], funcs, vars).ToString(); if (!namespaces.ContainsKey(nameOfSpace)) { return(false); } else { return(namespaces[nameOfSpace].ContainsKey(nameVar)); } } } //SetVar и GetVar будут реализованые в програмее, а не в библиотеке. //если это задать переменную if (cmd.StartsWith("SetVar")) { cmd = cmd.Remove(0, 6).Trim(); //убираем "SetVar" и пробелы cmd = cmd.Remove(0, 1); //убираем ( cmd = cmd.Remove(cmd.Length - 1, 1); //убираем ) string[] parameters = GetPars(cmd); //получаем параметры; if (parameters.Length < 2) //если параметров менее 2, выходим { return(parameters); } string nameVar = RunCmd(parameters[0], funcs, vars).ToString(); //получаем имя переменной string param = RunCmd(parameters[1], funcs, vars).ToString(); //получаем значение в виде строки object value = RunCmd(parameters[1], funcs, vars); //получаем значение if (value == null) { MessageBox.Show("Значение " + param + " не было сохранено", "Ошибка"); return(null); } if (parameters.Length == 2)//если пространство имён не указано { vars[nameVar] = value; } else//если указано { string nameOfSpace = RunCmd(parameters[2], funcs, vars).ToString(); if (!namespaces.ContainsKey(nameOfSpace)) { namespaces.Add(nameOfSpace, new Dictionary <string, object>()); } namespaces[nameOfSpace][nameVar] = value; } return(parameters); } //если это получить переменную if (cmd.StartsWith("GetVar")) { cmd = cmd.Remove(cmd.Length - 1, 1).Remove(0, 6).Trim(); //убираем ),"GetVar" и пробелы cmd = cmd.Remove(0, 1); //убираем ( var parameters = GetPars(cmd); //получаем праметры if (parameters.Length == 0) //если параметров нет { return(parameters); } try { string nameVar = RunCmd(parameters[0], funcs, vars).ToString(); return(parameters.Length == 1? vars[nameVar] : namespaces[RunCmd(parameters[1], funcs, vars).ToString()][nameVar]);//пытаемся достать значение переменной по имени } catch { MessageBox.Show("В GetVar не найдена переменная с именем " + RunCmd(parameters[0], funcs, vars).ToString()); return(parameters); } } //для цикла Repeat if (cmd.StartsWith("repeat") || cmd.StartsWith("async repeat") || cmd.StartsWith("allasync repeat")) { bool asynced = false; //выполнять цикл в отдельном потоке bool allasynced = false; //выполнить все сразу if (cmd.StartsWith("allasync ")) { allasynced = true; cmd = cmd.Remove(0, 9); } else if (cmd.StartsWith("async ")) { asynced = true; cmd = cmd.Remove(0, 6); } cmd = cmd.Remove(0, 6).Trim().Remove(0, 1); //убираем "repeat", пробелы и ( string param = cmd.Substring(0, cmd.IndexOf("{")).Trim(); //получаем параметр в виде строки param = param.Remove(param.LastIndexOf(")"), param.Length - param.LastIndexOf(")")); //убираю последнюю ) и всё после неё int count; //счётчик выполнения //получаю значение счётчика try { count = (int)RunCmd(param, funcs, vars); } catch { MessageBox.Show("В Repeat передано значение типа, несовместимого с Int", "Ошибка"); return(null); } string sc = cmd.Substring(cmd.IndexOf("{"), cmd.Length - cmd.IndexOf("{")); //получаю скрипт sc = sc.Remove(sc.Length - 1, 1).Remove(0, 1).Trim(); //убираю { и }, пробелы //новый поток дял выполнения Thread th = new Thread(() => { while (count > 0) //пока не кончится счётчик { if (allasynced) //если полный асинхрон, запускаю отдельно { ExecScript(sc, vars, funcs); } else { foreach (var command in GetCommands(sc)) //перебираю и запускаю все поочереди { RunCmd(command.Trim(), funcs, vars); //выполняю очередную команду } } count--; } }); th.Start(); //запускаю поток if (!asynced) //ждём, если синхронно { th.Join(); } return(null); } //если это опеределение функции func name(){} if (cmd.StartsWith("func ") || cmd.StartsWith("async func ")) { Func f = new Func(); //создаём новую функцию if (cmd.StartsWith("async func ")) //если это асинхронная { f.asyncFunc = true; cmd = cmd.Remove(0, 6); //убираем "async " } cmd = cmd.Remove(0, 5); //убираем "func " f.name = cmd.Substring(0, cmd.IndexOf('(')); //достаём имя //беру параметры f.prs = cmd.Substring(cmd.IndexOf('(') + 1, cmd.IndexOf(')') - cmd.IndexOf('(') - 1).Replace(" ", "").Split(',').ToList(); cmd = cmd.Remove(0, cmd.IndexOf('{') + 1); //достаю скрипт f.script = cmd.Remove(cmd.Length - 1); funcs.Add(f); //добавляю новую функцию return(null); } //если нашли пользовательскую функцию if (funcs.Any(c => c.name == cmd.Substring(0, cmd.IndexOf('(')))) { //находим эту функцию Func f = funcs.Find(c => c.name == cmd.Substring(0, cmd.IndexOf('('))); StringBuilder scb = new StringBuilder(f.script);//получаем скрипт функции //получаем параметры пользовательской функции var parameters = GetPars(cmd.Substring(cmd.IndexOf('(') + 1, cmd.LastIndexOf(')') - cmd.IndexOf('(') - 1)); int count = 0; for (int i = 0; i < scb.Length; i++) { if (scb[i] == '\"') { count++; } else if (scb[i] == '(' && count % 2 == 0) { if (scb[i + 1] == ')') { continue; } else { int lastBracket = 1; for (int sim = i + 1; sim < scb.Length; sim++) { if (scb[sim] == '(') { lastBracket++; } else if (scb[sim] == ')') { lastBracket--; } if (lastBracket == 0) { lastBracket = sim; break; } } string param = scb.ToString().Substring(i + 1, lastBracket - (i + 1)); var cmdPars = GetPars(param); for (int fPar = 0; fPar < f.prs.Count; fPar++) { for (int par = 0; par < cmdPars.Length; par++) { if (cmdPars[par] == f.prs[fPar]) { cmdPars[par] = parameters[fPar]; } } } scb.Remove(i + 1, param.Length); scb.Insert(i + 1, string.Join(",", cmdPars)); } } } string sc = scb.ToString(); if (f.asyncFunc)//если асинхронное { ExecScript(sc, vars, funcs); return(null); } else//обычное выполнение { var coms = GetCommands(sc); for (int c = 0; c < coms.Count; c++) { try { RunCmd(coms[c], funcs, vars); } catch (ReturnExeption e) { var value = RunCmd(e.Message, funcs, vars); if (value is object[]) { return((value as object[]).First()); } else { return(value.ToString()); } } } } return(null); } string script = cmd.Substring(0, cmd.IndexOf('(')); //получаю первое ключевое слово Meth meth = meths.Find(m => m.name == script); //ищу такой метод if (meth == null) //если метод не нашёл - шлю нафиг { MessageBox.Show(string.Format("Команда не найдена! \"{0}\"", script) + ". Выполнение прервано!"); return(null); } cmd = cmd.Remove(0, script.Length + 1); //убираю ключевое слово+ первая '(' cmd = cmd.Remove(cmd.Length - 1).Trim(' '); //убираю последнее ')' и пробелы string[] stringPars = GetPars(cmd); //беру оставшиеся параметры stringPars.AsParallel().ForAll(p => p = p.Trim(' ')); //чищу все параметры от пустышек List <object> pars = new List <object>(); //создаю объект параметров for (int i = 0; i < stringPars.Length; i++) { ParType p = GetTypeOfParam(stringPars[i].Trim(' '));//получаю тип параметра и его значение в переменные switch (p) { case ParType.String: pars.Add(str); break; case ParType.Double: pars.Add(doub); break; case ParType.Int: pars.Add(integer); break; case ParType.Boolean: pars.Add(boolean); break; case ParType.Method: if (stringPars[i] == "") { break; } var value = RunCmd(stringPars[i], funcs, vars); pars.Add(value is object[]? (value as object[]).First() : value); //если тип переменной-метод, запускаю и сохраняю результат break; } } try { return(meth.m.Invoke(null, new object[] { pars.ToArray() })); } catch (Exception e) { MessageBox.Show(e.Message); return(null); } }//выполнить одну команду
public void Load(string name) { if (string.IsNullOrEmpty(name)) { return; } var file = new ContentFile(); try { var path = _game.Config.ContentManager.GetUnitStatPath(name); _logger.Debug($"Loading {name}'s Stats from path: {Path.GetFullPath(path)}!"); var text = File.ReadAllText(Path.GetFullPath(path)); file = JsonConvert.DeserializeObject <ContentFile>(text); } catch (ContentNotFoundException notfound) { _logger.Warn($"Stats for {name} was not found: {notfound.Message}"); return; } BaseHp = file.GetFloat("Data", "BaseHP", BaseHp); BaseMp = file.GetFloat("Data", "BaseMP", BaseMp); BaseDamage = file.GetFloat("Data", "BaseDamage", BaseDamage); AttackRange = file.GetFloat("Data", "AttackRange", AttackRange); MoveSpeed = file.GetInt("Data", "MoveSpeed", MoveSpeed); Armor = file.GetFloat("Data", "Armor", Armor); SpellBlock = file.GetFloat("Data", "SpellBlock", SpellBlock); BaseStaticHpRegen = file.GetFloat("Data", "BaseStaticHPRegen", BaseStaticHpRegen); BaseStaticMpRegen = file.GetFloat("Data", "BaseStaticMPRegen", BaseStaticMpRegen); AttackDelayOffsetPercent = file.GetFloat("Data", "AttackDelayOffsetPercent", AttackDelayOffsetPercent); HpPerLevel = file.GetFloat("Data", "HPPerLevel", HpPerLevel); MpPerLevel = file.GetFloat("Data", "MPPerLevel", MpPerLevel); DamagePerLevel = file.GetFloat("Data", "DamagePerLevel", DamagePerLevel); ArmorPerLevel = file.GetFloat("Data", "ArmorPerLevel", ArmorPerLevel); SpellBlockPerLevel = file.GetFloat("Data", "SpellBlockPerLevel", SpellBlockPerLevel); HpRegenPerLevel = file.GetFloat("Data", "HPRegenPerLevel", HpRegenPerLevel); MpRegenPerLevel = file.GetFloat("Data", "MPRegenPerLevel", MpRegenPerLevel); AttackSpeedPerLevel = file.GetFloat("Data", "AttackSpeedPerLevel", AttackSpeedPerLevel); IsMelee = file.GetString("Data", "IsMelee", IsMelee ? "Yes" : "No").Equals("yes"); PathfindingCollisionRadius = file.GetFloat("Data", "PathfindingCollisionRadius", PathfindingCollisionRadius); GameplayCollisionRadius = file.GetFloat("Data", "GameplayCollisionRadius", GameplayCollisionRadius); Enum.TryParse <PrimaryAbilityResourceType>(file.GetString("Data", "PARType", ParType.ToString()), out var tempPar); ParType = tempPar; for (var i = 0; i < 4; i++) { SpellNames[i] = file.GetString("Data", $"Spell{i + 1}", SpellNames[i]); } for (var i = 0; i < 4; i++) { SpellsUpLevels[i] = file.GetIntArray("Data", $"SpellsUpLevels{i + 1}", SpellsUpLevels[i]); } MaxLevels = file.GetIntArray("Data", "MaxLevels", MaxLevels); for (var i = 0; i < 8; i++) { ExtraSpells[i] = file.GetString("Data", $"ExtraSpell{i + 1}", ExtraSpells[i]); } for (var i = 0; i < 6; i++) { Passives[i].PassiveNameStr = file.GetString("Data", $"Passive{i + 1}Name", Passives[i].PassiveNameStr); Passives[i].PassiveLuaName = file.GetString("Data", $"Passive{i + 1}LuaName", Passives[i].PassiveLuaName); Passives[i].PassiveLevels = file.GetMultiInt("Data", $"Passive{i + 1}Level", 6, -1); } }
private XElement AddParameter(string name, string shortName, DataType datatype, InOut inout, ParType parType, string defaultVal) { var parameter = new XElement("Parameter", new XAttribute("Name", name), new XAttribute("ShortName", shortName), new XAttribute("DataType", datatype.ToString()), new XAttribute("Usage", inout.ToString()), new XAttribute("Type", parType.ToString()), new XAttribute("DefaultValue", defaultVal), new XAttribute("Value", defaultVal) ); return(parameter); }
public Parameter(string str, ParType _type) : this(str) { ptype = _type; if (ptype == ParType.Integer) par = Lib.ToInt((string)par); if (ptype == ParType.Double) par = Lib.ToDouble((string)par); }