- 好友
- 27
- 在线时间
- 627 小时
- 最后登录
- 2024-10-8
联机技术研发组
自由骑士 联机ID:K2SB
- UID
- 2758158
- 第纳尔
- 2652
- 精华
- 1
- 互助
- 93
- 荣誉
- 38
- 贡献
- 0
- 魅力
- 112
- 注册时间
- 2016-7-15
鲜花( 1381) 鸡蛋( 32)
|
本帖最后由 k2木有小鸡鸡 于 2018-12-4 14:54 编辑
有感于一个modder问我的问题,其实骑砍的报错信息是很关键的东西,
根据报错信息寻找到真正出错的地方是比较简单的。
1, 看懂报错中的超长operation数字
先说下结论,下面分析的弄不明白的可以不看了
如果报错操作数是-214748(注意这里是一个负数)开头
2147483648+报错信息中的操作数(因为这个数是负的实际上是相减)=源码中的操作数
源码错误的代码为(neg|源码中的操作数,........):
如果报错操作数是 107374开头
-1073741824+报错信息中的操作数=源码中的操作数
源码错误的代码为(this_or_next|源码中的操作数,........):
例如如下报错:
SCRIPT WARNING ON OPCODE -2147481298: Invalid Player ID: -15; LINE NO: 1:
At Mission Template mst_multiplayer_dm trigger no: 60 consequences. At Mission Template mst_multiplayer_bt trigger no: 60 consequences. [!] SCRIPT WARNING ON OPCODE -2147481298(这是报错操作号): Invalid Player ID: -15(这是报错原因); LINE NO: 1(这是报错行号):
At Mission Template mst_multiplayer_dm(这是报错触发器的名字) trigger no: 60(这是报错触发器在mission中的编号) consequences. At Mission Template mst_multiplayer_bt trigger no: 60 consequences. [!]
通常根据script的名字和op编号, 就可以比较容易的查到需要修改的地方。但是你会遇到这种情况,就是operation号码超出了header里面的范围很多,是-214747****这样的。
实际上这些超长的报错op编号,是由于本身操作前面加了取反符号neg|
neg = 0x80000000 # (neg|<operation_name>, ...), # Used in combination with conditional operations to invert their results.
那么想知道真正出错的代码, 实际上是存在这样的关系 出错数字= neg|你源码中的operation = 0x80000000|你源码中的operation
例如-2147481298的报错数字对应的其实是neg|2350
只需要反算回来即可。
也就是实际上, 如果你遇到的报错信息中的op超长,你需要用2147483648加上报错数字(注意这通常是一个负数)即可得到操作前的编号。
例如报错数字为-2147481298,就用2147483648+(-2147481298)=2350.
str_store_player_username = 2350
那么对应的代码错误应该是neg|str_store_player_username (当然这本身就是一个错误的用法,str_store_player_username不应该用来neg|与此同时,报错信息里面的agent_id也不能为负数)
如果报错信息如下
SCRIPT WARNING ON OPCODE 1073744174: Invalid Player ID: -15; LINE NO: 1:
At Mission Template mst_multiplayer_bt trigger no: 61 consequences. At Mission Template mst_multiplayer_bt trigger no: 61 consequences.
OPCODE 1073744174实际上是代码中的 this_or_next|原操作符, 也就是0x40000000|原操作符,为了得到原操作符,需要把
-1073741824+报错操作号=-1073741824+1073744174=2350 也就得到了操作符为
str_store_player_username = 2350
那么对应的代码错误应该是this_or_next|str_store_player_username
题外话:
例如我在script里面使用了(neg|agent_is_human, *********),实际上在script.txt里面,编译结果是2147485352
agent_is_human = 1704
2147485352- 2147483648=1704
也就是说你要想从txt里面的操作号反推代码中的,那么运算应该是
txt中的编译后数字 - 2147483648=neg|实际operation
2, Mission Templates报错编号的处理
通常报错信息会告诉你,出错的mission是什么, 在这组里面的编号是多少,例如At Mission Template mst_multiplayer_dm trigger no:60
但是在同一个mission的触发器非常多的情况下,查找一个mission是相当困难的(目前我维护的联机模式的一个mission的触发器往往有100多个,有好几个作者,写到了好几个文件里面去),一个个数数也很麻烦,那么就可以用txt或者反编译工具来帮助查找。
打开你的mission_templates.txt 找到mst_multiplayer_dm,如下:
- mst_multiplayer_dm multiplayer_dm 2 -1
- You_lead_your_men_to_battle.
- 64 0 4112 0 16 1 0
- 1 4112 0 16 1 0
- 2 4112 0 16 1 0
- 3 4112 0 16 1 0
- 4 4112 0 16 1 0
- 5 4112 0 16 1 0
- 6 4112 0 16 1 0
- 7 4112 0 16 1 0
- 8 4112 0 16 1 0
- 9 4112 0 16 1 0
- 10 4112 0 16 1 0
- 11 4112 0 16 1 0
- 12 4112 0 16 1 0
- 13 4112 0 16 1 0
- 14 4112 0 16 1 0
- 15 4112 0 16 1 0
- 16 4112 0 16 1 0
- 17 4112 0 16 1 0
- 18 4112 0 16 1 0
- 19 4112 0 16 1 0
- 20 4112 0 16 1 0
- 21 4112 0 16 1 0
- 22 4112 0 16 1 0
- 23 4112 0 16 1 0
- 24 4112 0 16 1 0
- 25 4112 0 16 1 0
- 26 4112 0 16 1 0
- 27 4112 0 16 1 0
- 28 4112 0 16 1 0
- 29 4112 0 16 1 0
- 30 4112 0 16 1 0
- 31 4112 0 16 1 0
- 32 8208 0 16 1 0
- 33 8208 0 16 1 0
- 34 8208 0 16 1 0
- 35 8208 0 16 1 0
- 36 8208 0 16 1 0
- 37 8208 0 16 1 0
- 38 8208 0 16 1 0
- 39 8208 0 16 1 0
- 40 8208 0 16 1 0
- 41 8208 0 16 1 0
- 42 8208 0 16 1 0
- 43 8208 0 16 1 0
- 44 8208 0 16 1 0
- 45 8208 0 16 1 0
- 46 8208 0 16 1 0
- 47 8208 0 16 1 0
- 48 8208 0 16 1 0
- 49 8208 0 16 1 0
- 50 8208 0 16 1 0
- 51 8208 0 16 1 0
- 52 8208 0 16 1 0
- 53 8208 0 16 1 0
- 54 8208 0 16 1 0
- 55 8208 0 16 1 0
- 56 8208 0 16 1 0
- 57 8208 0 16 1 0
- 58 8208 0 16 1 0
- 59 8208 0 16 1 0
- 60 8208 0 16 1 0
- 61 8208 0 16 1 0
- 62 8208 0 16 1 0
- 63 8208 0 16 1 0
- 91
复制代码
最后的这个数字91,表示的是mst_multiplayer_dm一共有多少个触发器,
从这一行起,下面的触发器依次编号是从0开始,那么计算出编号为报错的编号就是用91这样的触发器数量这一行的行号,加上报错信息中的编号加一。
譬如, 91这一行的行号是1356,那么用1356+报错信息中的trigger no:60 得到1416再加一得到1417。1417行内容如下:
-25.000000 0.000000 0.000000 0 68 2071 1 1224979098644774912 2147485998 2 10 -15 4 0 1073741855 2 144115188075856328 6 31 2 144115188075856328 4 2147485355 1 1224979098644774912 1724 2 1224979098644774913 1224979098644774912 404 2 1224979098644774914 1224979098644774913 418 0 1073741855 2 1224979098644774914 360287970189640562 1073741855 2 1224979098644774914 360287970189640550 1073741855 2 1224979098644774914 360287970189640553 1073741855 2 1224979098644774914 360287970189640565 1073741855 2 1224979098644774914 360287970189640556 31 2 1224979098644774914 360287970189640559 2090 2 1224979098644774912 128 1721 2 1224979098644774912 100 3 0 4 0 2147484066 0 1700 1 1224979098644774915 31 2 1224979098644774915 1224979098644774912 2133 2 144115188075856385 1224979098644774912 2133 2 144115188075856386 0 2133 2 144115188075856387 0 3 0 417 0 2133 2 144115188075856372 1 505 3 1224979098644774912 28 0 505 3 1224979098644774912 27 0 505 3 1224979098644774912 29 0 505 3 1224979098644774912 30 0 4 0 2147485355 1 1224979098644774912 1724 2 1224979098644774913 1224979098644774912 508 3 1224979098644774913 110 0 3 0 4 0 1073741854 2 144115188075856388 1 30 2 144115188075856389 101 1 2 936748722493064176 1224979098644774912 5 0 31 2 144115188075856328 6 30 2 144115188075856371 1 2147483679 2 144115188075856205 1 1 3 936748722493064117 1224979098644774912 0 5 0 2147483679 2 144115188075856328 6 2147483679 2 144115188075856328 0 2147483679 2 144115188075856328 7 2147483679 2 144115188075856328 2 2147483679 2 144115188075856328 4 2211 1 1224979098644774916 33 3 1224979098644774916 720575940379279880 720575940379280176 1 3 936748722493064117 1224979098644774912 0 3 0 1724 2 1224979098644774913 1224979098644774912 4 0 417 0 30 2 1224979098644774913 0 2350 2 50 1224979098644774913 404 2 1224979098644774917 1224979098644774913 2322 2 51 1224979098644774917 473 1 216172782113787669 528 3 1224979098644774918 1224979098644774913 332 2105 2 1224979098644774918 1 508 3 1224979098644774913 332 1224979098644774918 3 0
这是一个-25, 0, 0的触发器, 触发器如果是负数,则表示是系统给定的特殊触发场景, 查阅一下header_triggers.py就能得到
ti_on_agent_spawn = -25.0 #can only be used in module_mission_templates triggers
那么也就是说,这是一个(ti_on_agent_spawn,0,0)的触发器,再加上给出的操作号很容易就定位到了bug的位置。
如果触发器本身非常的长,或者script本身过长,定位到了多个可能出错的地方,还有最终的解决办法:反编译.http://bbs.mountblade.com.cn/forum.php?mod=viewthread&tid=471360
报错信息还有一条就是行号,就是那个script warning on op code后面有一个line no:
如果你找到了script或者触发器,但是却发现,自己写了很多很多注释,写的时候为了方便排版 使用了一些空格,那么行号就对应不上,那么反编译工具可以帮到你,使用反编译得到的代码,查找对应的script或者触发器,然后从内容的第一行就是line no1,往下算出出错的行号即可。最后返回自己的源码修改出错的地方。反编译的作用就是帮你把格式弄成和报错信息一致的样子,方便你去查阅信息。
最后,养成良好的代码习惯 :
bug不隔夜,文档注释要规范,不一定要详尽,最好每个类型都区分前缀。多写script少在mission tempates里面堆积大坨代码,因为报错的script名总是可靠的,所以对debug非常有利。
|
评分
-
参与人数 1 | 荣誉 +1 |
第纳尔 +100 |
互助 +1 |
收起
理由
|
小丑遊戲
| + 1 |
+ 100 |
+ 1 |
文章不错,继续努力! |
查看全部评分
鲜花鸡蛋一尾锦鲤 在2018-12-4 22:29 送朵鲜花 并说:我非常同意你的观点,送朵鲜花鼓励一下 达尔克内斯 在2018-12-4 13:17 送朵鲜花 并说:我非常同意你的观点,送朵鲜花鼓励一下
|