我正在使用JavaScript和canvas创建一个基本的RPG游戏引擎原型。我还在制作纸上的一些设计规格,我遇到了一些问题,我不太清楚如何处理。
我将拥有一个具有Attribute对象数组的Character对象。属性看起来像这样:
function(name, value){
this.name = name;
this.value = value;
...
}
角色还具有根据属性计算的“技能”。技能值也可以由用户输入的公式确定。一个合法的公式看起来像这样:
((@attribute1Name + (@attribute2Name / 2) * 5)
@符号后面的任何文字表示属于该字符的属性的名称。该公式将作为字符串输入文本字段。
我遇到的问题是了解解析和评估此公式的正确方法。最初,我的计划是对属性名称进行简单替换并eval表达式(如果无效,则eval将失败)。但是,这会带来一个问题,因为它允许JavaScript注入现场。我假设我需要某种类似于中缀计算器的FSM来解决这个问题,但我的计算理论有点生疏(感谢企业界!)。我真的不是要求别人把代码交给我,因为我想得到你对这个问题的最佳解决方案的意见吗?
编辑:感谢您的回复。不幸的是,生活让我很忙,我还没有尝试过解决方案。当我得到结果(好的或坏的)时会更新。
答案 0 :(得分:2)
不同的想法,因此另外一个建议:
eval()
工作正常,没有必要重新发明轮子。
假设您的公式语言中只有少量且固定数量的变量,那么扫描表达式并确认您遇到的所有内容都是括号,运算符或变量名之一就足够了。我认为没有办法将这些部分组合成一段可能对eval产生恶意副作用的代码。
所以:
可能是在将风险降低到(接近?)0的同时最少的工作和代码的妥协。最坏的情况是,滥用者可以在变量名称上用括号来试图执行变量。
答案 1 :(得分:0)
我认为,不是让他们把整个公式放进去,你可以拥有具有操作和值的select
标签,让他们选择。
即。一组带有attribute-operation-number的标签:
<select> <select> <input type="text">
@attribute1Name1 + (check if input is number)
@attribute1Name2 -
@attribute1Name3 *
@attribute1Name4 /
等
答案 2 :(得分:0)
有一个非常简单的解决方案:只需输入一个普通的JavaScript公式(即,就像为对象编写方法一样)并使用this
来引用您正在处理的对象。
要在评估方法时更改this
,请使用apply()
或call()
(see this answer)。
答案 3 :(得分:0)
我最近写了一个类似的应用程序。我可能投入了太多的工作,但我走了整整9码并写了扫描仪和解析器。
扫描仪将文本转换为一系列令牌;标记是由标记类型和值组成的简单对象。对于标点符号,value = character,对于数字,值将是对应于数字的数值的整数,对于变量,它将是(引用)变量对象,其中该变量将位于列表中具有名称的对象。相同的变量对象=相同的变量,natch。
解析器是一个简单的强力递归下降解析器。 Here's the code
我的解析器执行逻辑表达式,AND / OR代替+/-,但我认为你可以看到这个想法。有几个级别的表达式,每个表达式尝试尽可能多地组合它们,并调用较低级别来解析嵌套构造。完成后,我的解析器生成了一个包含表示表达式的树结构的Node。
在你的程序中,我猜你可以存储那个Node,因为它的结构基本上代表了它的评估公式。
考虑到所有这些工作,我会理解陷入并使用eval是多么诱人!
答案 4 :(得分:0)
我对通过最简单的手段完成任务感到着迷。
这是另一种方法:
这里的理由是,一旦你摆脱了“* before +”和括号的复杂性,剩下的计算就非常简单了。
答案 5 :(得分:0)
您可以查看在沙箱中运行用户定义的代码以防止攻击:
Is It Possible to Sandbox JavaScript Running In the Browser?