ldmud支持用python写efun然后在游戏内调用,python具有丰富的第三方库,这样就使得driver的能力获得了扩展。
下面就实际举个使用python扩展efun的例子
驱动下载
环境配置使用的是LDMud 3.6.5 (3.6.5-5-gf597dee3) 编译时开启了python,windows下我已经编译好了具体的驱动,使用的lib是我移植的风云2005,我已经把驱动和lib打包上传,下载地址如下:
链接: https://pan.baidu.com/s/1ba0iQ-uyFebeeeC4XkRe9Q?pwd=489y 提取码: 489y 复制这段内容后打开百度网盘手机App,操作更方便哦
如果有能力自己配置driver编译的话,也可以自己编译,下载好压缩包后解压缩至c盘根目录下,然后进入C:\mud\
mud目录
下面来看下mud目录的具体构成,mud目录下7个子目录:
- bin内为可执行程序
- erq内空目录
- examples目录为python扩展的脚本例子
- include为driver所需的各种头文件,这些也存在于lib文件夹的\sys内
- python目录为driver所需要的python环境
- share目录是man帮助文件
有的小伙伴可能会讲我不想放在C盘下,可以放在其他目录么,放在其他目录也可以,那样的话:一键运行.bat就无法直接使用,需要你自己配置才能一键启动。有的小伙伴可能会问为什么不编译一个放在D盘下的,那是因为我是在云服务器上编译的,我的云服务器只有一个盘符C。
python环境
今天我要分享的重点是使用python联合编程,那么是一定要加载python的。
在运行driver加载python之前,首先是本机也一定要安装python,可以去python官网下载,这里我是用的版本是:Python 3.9.12 - March 23, 2022,直接选择Download Windows installer (64-bit) 下载安装,下载好运行安装包选择Customize installation可自定义路径(我选这个),你也可以选择默认安装路径,勾选Add Python 3.9.12 to PATH是把Python的安装路径添加到系统环境变量的Path变量中,这步一定要选择。
这样你的本机就安装好了python,本机没有python也无法在driver内使用python。
python efun
下面来看一下C:\mud\bin\一键运行.bat的内容:
C:
cd \mud\bin
set PYTHONHOME=/cygdrive/c/mud/python
set HOME=/cygdrive/c/mud/python
ldmud --python-script C:\mud\examples\startup.py 3333
pause
关键的内容是ldmud --python-script C:\mud\examples\startup.py 3333
,解释一下意思就是启动的时候,加载python efun的文件内容为C:\mud\examples\startup.py,同时端口设定为3333,ldmud在启动时候支持很多命令行,参数具体的可以看:https://github.com/ldmud/ldmud/blob/master/doc/driver/invocation
如果不想加载python那么可以去掉--python-script C:\mud\examples\startup.py
这样就不使用python了。
下面来看一下C:\mud\examples\startup.py的内容
# This module can be used as a startup script.
#
# It will load all the other modules that offer the ldmud_efun entry point.
# In the configuration file ~/.ldmud-efuns single efuns can be deactivated
# with entries like this:
#
# [efuns]
# name_of_the_efun = off
from ldmudefuns.startup import startup
import ldmud
def python_return(val):
"""Return the given value to check the
type conversion between Python and LPC."""
return val
def python_abs(arg:int):
return abs(arg)
ldmud.register_efun("python_return", python_return)
ldmud.register_efun("abs",python_abs)
startup()
import的部分是必不可少的,然后是在下面我写了两个简单的python efun,一个是python_return,它的做就用是直接返回函数参数,另外一个就是python_abs(arg:int) 这个函数的作用就是返回一个绝对值,这两个简单efun 都是起到测试的作用,函数的下面ldmud.register_efun("python_return", python_return)
的意思就是把这两个python的函数注册成lpc的efun名字分别是python_return
和python_abs
,这里efun的名字你可以自己指定比如注册成ldmud.register_efun("abs",_abs)
那么efun的名字就是_abs
。最后一行 startup()
这个不用解释了。
编写好python 文件后保存退出,运行C:\mud\bin\一键运行.bat driver跑起来后能看到
C:\mud\bin>ldmud --python-script E:\bank\fengyun_ldmud_with_python\ldmud_with_python\examples\startup.py 3333
2022.07.28 17:31:17 LDMud 3.6.5 (3.6.5-5-gf597dee3) (development)
2022.07.28 17:31:17 Seeding PRNG from /dev/urandom.
2022.07.28 17:31:17 TLS deactivated.
Registering Python efun python_efun_help
Registering Python efun python_reload
Registering Python efun json_parse
Registering Python efun json_serialize
//...此处省略若干
LDMud ready for users.
这说明已driver经成功运行,登陆游戏本机3333端口,使用wiz账号可以做一个测试
eval printf("%O",python_abs(-1))
显示是1说明python efun 运行良好,以上是自带简单的python的例子。
复杂示例
下面我们来一个复杂有点的例子,比如目前游戏里面的时间系统都很简单,我想给游戏增加一些复杂的,比如农历、黄历、二十四节气、节假日、星次、每日凶煞、每日值神、农历建除十二神、农历每日宜忌、彭祖百忌、每日五行、二十八星宿、天干地支、农历生辰八字、时辰凶吉等,甚至可以考虑加入个算卦的npc来卜卦,那么可以怎么办呢?
如果用lpc从头开写工作量是很大的,这时候python的优越性就展现出来了,我直接登陆 https://github.com/ 搜索python 然后我找了一个日历的库 https://github.com/OPN48/cnlunar ,很好这库还可以直接使用pip安装,那就更简单了。
下面开始:
打开cmd命令行,然后运行pip3 install cnlunar
直接安装库,安装好之后需要再次运行一次pip3 install cnlunar
,这样系统会提示你Requirement already satisfied: cnlunar in c:\python\python39\lib\site-packages (0.0.7) 这里划重点,要记住。
这样你就知道你这个程序包的位置了,这里个位置就是一开始你安装python选的自定义路径有关,比如我的python安装的位置是c:\python\,cnlunar库安装好了,然后呢我们就仿照 https://github.com/OPN48/cnlunar/blob/master/cnlunar/demo.py 写一个可以在driver提lpc调用的efun,这里为了简单起见我直接粘贴我写好的
#coding:utf-8
# This module can be used as a startup script.
#
# It will load all the other modules that offer the ldmud_efun entry point.
# In the configuration file ~/.ldmud-efuns single efuns can be deactivated
# with entries like this:
#
# [efuns]
# name_of_the_efun = off
from ldmudefuns.startup import startup
import ldmud
import datetime
import cnlunar
def p_cnlunar():
a = cnlunar.Lunar() # 为空为当前时间 #
dic = {
'日期': str(a.date),
'农历数字': str((a.lunarYear, a.lunarMonth, a.lunarDay, '闰' if a.isLunarLeapMonth else '')),
'农历': '%s %s[%s]年 %s%s' % (a.lunarYearCn, a.year8Char, a.chineseYearZodiac, a.lunarMonthCn, a.lunarDayCn),
'星期': str(a.weekDayCn),
'今日节日': str((a.get_legalHolidays(), a.get_otherHolidays(), a.get_otherLunarHolidays())),
'八字': str(' '.join([a.year8Char, a.month8Char, a.day8Char, a.twohour8Char])),
'今日节气': str(a.todaySolarTerms),
'下一节气': str((a.nextSolarTerm, a.nextSolarTermDate, a.nextSolarTermYear)),
'今年节气表': str(a.thisYearSolarTermsDic),
'季节': str(a.lunarSeason),
'今日时辰': str(a.twohour8CharList),
'时辰凶吉': str(a.get_twohourLuckyList()),
'生肖冲煞': str(a.chineseZodiacClash),
'星座': str(a.starZodiac),
'星次': str(a.todayEastZodiac),
'彭祖百忌': str(a.get_pengTaboo()),
'彭祖百忌精简': str(a.get_pengTaboo(long=4, delimit='<br>')),
'十二神': str(a.get_today12DayOfficer()),
'廿八宿': str(a.get_the28Stars()),
'今日三合': str(a.zodiacMark3List),
'今日六合': str(a.zodiacMark6),
'今日五行': str(a.get_today5Elements()),
'纳音': str(a.get_nayin()),
'九宫飞星': str(a.get_the9FlyStar()),
'吉神方位': str(a.get_luckyGodsDirection()),
'今日胎神': str(a.get_fetalGod()),
'神煞宜忌': str(a.angelDemon),
'今日吉神': str(a.goodGodName),
'今日凶煞': str(a.badGodName),
'宜忌等第': str(a.todayLevelName),
'宜': str(a.goodThing),
'忌': str(a.badThing),
'时辰经络': str(a.meridians)
}
return ldmud.Mapping(dic)
ldmud.register_efun("p_cnlunar", p_cnlunar)
startup()
下面来看下内容:
from ldmudefuns.startup import startup
import ldmud
这些是必不可少的内容不解释了
import datetime
import cnlunar
从这里开始就是复制了 https://github.com/OPN48/cnlunar/blob/master/cnlunar/demo.py 里面的内容并且定义了一个python函数def p_cnlunar()
为了简单起见这个函数不需要参数直接返回的内容是ldmud.Mapping(dic)
也就是一个lpc mapping格式的数据,需要注意的是这里使用了str()把python dic 里面的内容强制转换成了string,把上述的代码保存为C:\mud\examples\startup.py
然后直接运行C:\mud\bin\一键运行.bat 你会发现 cmd line里面提示
Traceback (most recent call last):
File "C:\mud\examples\startup.py", line 14, in <module>
import cnlunar
ModuleNotFoundError: No module named 'cnlunar'
思考下,这说明了什么?这说明没有cnlunar模块,可是刚刚我的确pip3安装了cnlunar了啊,这是因为你是在本机python环境下安装了这个模块,但是ldmud需要的python环境里面没有,那么该怎么办呢?
还记的Requirement already satisfied: cnlunar in c:\python\python39\lib\site-packages (0.0.7) 吗
这就好办了,打开c:\python\python39\lib\site-packages文件夹把这个复制到C:\mud\python\lib\python3.9\里面,替换确认,或者是打开c:\python\python39\lib\site-packages找到cnlunar的安装目录cnlunar和cnlunar-0.0.7.dist-info目录直接复制这两个目录到C:\mud\python\lib\python3.9\site-packages目录内,这样我们ldmud需要的python环境里面就有了cnlunar模块了。
然后关掉cmd重新运行C:\mud\bin\一键运行.bat我们发现这次提示
C:\mud\bin>ldmud --python-script C:\mud\examples\startup.py 3333
2022.07.28 19:29:49 LDMud 3.6.5 (3.6.5-5-gf597dee3) (development)
2022.07.28 19:29:50 Seeding PRNG from /dev/urandom.
2022.07.28 19:29:50 TLS deactivated.
Registering Python efun python_efun_help
Registering Python efun python_reload
Registering Python efun json_parse
Registering Python efun json_serialize
//...此处省略若干
LDMud ready for users.
这就说明driver已经正确加载python脚本了,登陆游戏使用wiz账号继续做一个测试eval
printf("%O",p_cnlunar())
显示是:
>eval printf("%O",p_cnlunar())
([ /* #1 */
"农历": "二零二二 壬寅[虎]年 六月大三十",
"今日凶煞": "['往亡', '伏兵', '天吏', '受死', '破败', '月建转杀', '土王用事', '血支', '制日']",
"宜忌等第": "中次:凶胜于吉,遇德从宜亦从忌,不遇从忌不从宜。",
"忌": "['出行', '安床', '上表章', '冠带', '竖柱上梁', '开市', '修置产室', '开渠', '穿井', '安碓硙', '平治道涂', '破屋坏垣', '捕捉',
'畋猎', '栽种', '牧养', '营建', '苫盖', '缮城郭', '解除', '开仓', '选将', '招贤', '上册', '出师', '祈福', '疗目', '颁诏', '求嗣',
'举正直', '修宫室', '取鱼', '修仓库', '修饰垣墙', '施恩', '宣政事', '安抚边境', '针刺']",
"星次": "鹑火",
"吉神方位": "['喜神正南', '财神正南', '福神东南', '阳贵正东', '阴贵东南']",
"生肖冲煞": "马日冲鼠",
"农历数字": "(2022, 6, 30, '')",
"今日胎神": "仓库碓外西北",
"时辰凶吉": "['吉', '吉', '凶', '吉', '凶', '凶', '吉', '凶', '吉', '吉', '凶', '凶', '凶']",
"今日节气": "无",
"十二神": "('闭', '天牢', '黑道日')",
"今日五行": "['天干', '壬', '属水', '地支', '午', '属火', '纳音', '木', '属木', '廿八宿', '角', '宿', '十二神', '闭', '日']",
"彭祖百忌": "壬不泱水 更难提防,午不苫盖 屋主更张",
"星座": "狮子座",
"今日吉神": "['岁德', '六合', '不将', '大葬', '鸣吠', '不守塚', '官日', '天恩', '天医', '明星', '吉庆']",
"神煞宜忌": "((['岁德', '六合', '不将', '大葬', '鸣吠', '不守塚', '官日', '天恩', '天医', '明星', '吉庆'], ['往亡', '伏兵', '天吏',
'受死', '破败', '月建转杀', '土王用事', '血支', '制日']), (['经络', '安葬', '诉讼', '恤孤茕', '酝酿', '塞穴', '雪冤', '入宅', '覃恩',
'赴任'], ['出行', '安床', '上表章', '冠带', '竖柱上梁', '开市', '修置产室', '开渠', '穿井', '安碓硙', '平治道涂', '破屋坏垣', '捕捉',
'畋猎', '栽种', '牧养', '营建', '苫盖', '缮城郭', '解除', '开仓', '选将', '招贤', '上册', '出师', '祈福', '疗目', '颁诏', '求嗣',
'举正直', '修宫室', '取鱼', '修仓库', '修饰垣墙', '施恩', '宣政事', '安抚边境', '针刺']))",
"今年节气表": "{'小寒': (1, 5), '大寒': (1, 20), '立春': (2, 4), '雨水': (2, 19), '惊蛰': (3, 5), '春分': (3, 20),
'清明': (4, 5), '谷雨': (4, 20), '立夏': (5, 5), '小满': (5, 21), '芒种': (6, 6), '夏至': (6, 21), '小暑': (7, 7),
'大暑': (7, 23), '立秋': (8, 7), '处暑': (8, 23), '白露': (9, 7), '秋分': (9, 23), '寒露': (10, 8), '霜降': (10,
23), '立冬': (11, 7), '小雪': (11, 22), '大雪': (12, 7), '冬至': (12, 22)}",
"星期": "星期四",
"下一节气": "('立秋', (8, 7), 2022)",
"八字": "壬寅 丁未 壬午 庚戌",
"宜": "['经络', '安葬', '诉讼', '恤孤茕', '酝酿', '塞穴', '雪冤', '入宅', '覃恩', '赴任']",
"彭祖百忌精简": "壬不泱水<br>午不苫盖",
"廿八宿": "角木蛟",
"今日三合": "['狗', '虎']",
"今日六合": "羊",
"九宫飞星": "624579138",
"今日节日": "('', '', '')",
"纳音": "杨柳木",
"今日时辰": "['庚子', '辛丑', '壬寅', '癸卯', '甲辰', '乙巳', '丙午', '丁未', '戊申', '己酉', '庚戌', '辛亥', '壬子']",
"季节": "季夏",
"日期": "2022-07-28 19:29:50.168677",
"时辰经络": "心包"
])
Result = 0
说明python efun 运行正常,想象下自己重新写个农历时间efun得多耗时,就知道直接使用python有多香了。
如果一直使用python来编写efun的话python的水平也会提高,这样对于新手wiz来说等于又学习了python编程,一举 两得。