Command parser and reconstructor for minecraft commands in pure python (requires python3.7+).
This project currently supports minecraft 1.8 - 1.16
mcfunction.py is currently not on PyPi, but you can use the commad below
pip install git+https://git@github.com/Le0Developer/mcfunction.py.gitIf you need a specific version, use @
pip install git+https://git@github.com/Le0Developer/mcfunction.py.git@v0.3.1You can use the parse_command function to parse a command.
frommcfunctionimportparse_commandfrommcfunction.versions.mc_1_8.summonimportParsedSummonCommandcommand=parse_command('summon minecraft:ender_dragon ~ ~ ~')
# command is the parsed commandcommand: ParsedSummonCommand# for type-hinting# you can use 'str(command)' to construct the command from the parsed commandprint(command) # print() automatically calls str()print(repr(command)) # bypasses str() and lets you see the real 'command'# modify the node of the summoned entitycommand.entity.name='wither'# reconstruction will show the changed commandprint(command)You can create the ParsedCommand directly if you don't have a string for parse_command.
frommcfunctionimportnodesfrommcfunction.versions.mc_1_8.summonimportParsedSummonCommand# versions.mc_1_8 because the summon command were using was last changed in 1.8command=ParsedSummonCommand(
'summon', # first argument is always the command name (for alias support)nodes.NamespaceIDNode('minecraft', 'elder_guardian'),
nodes.PositionNode(
nodes.CoordinateNode(0, relative=True),
nodes.CoordinateNode(0, relative=True),
nodes.CoordinateNode(0, relative=True)
)
)
print(command)It's actually really simple. Let's assume you have a greet command and its
syntax is greet <target> [message].
Greet Command
fromdataclassesimportdataclassfrommcfunction.versionsimportCommand, ParsedCommand, Parserfrommcfunction.nodesimportEntityNode, RawNodefrommcfunction.parser_typesimportEntity, GreedyAny# you don't need to use dataclasses, you can create the __init__ yourself@dataclass()classParsedGreetCommand(ParsedCommand):
command: strtarget: EntityNode# the target of your commandreason: RawNode=None# raw text, but it's optional, so ' = None'# this is the construction function, this should return the command as# stringdef__str__(self):
ifself.reasonisnotNone:
# EntityNode and RawNode have a __str__ too, so you can just use# them in f-strings like thisreturnf'{self.command}{self.target}{self.reason}'returnf'{self.command}{self.target}'# now you can create your commandgreet=Command('greet', parsed=ParsedGreetCommand)
# add your syntaxgreet.add_variation(
# parses a 'Entity' and puts the parsed node into the 'target' fieldParser(Entity(), 'target'),
# 'GreedyAny' parses all the remaining arguments into a single nodeParser(GreedyAny(), 'reason')
)
# and add the variation without reasongreet.add_variation(
Parser(Entity(), 'target')
)
# you can use `greet.parse` to parse a command nowparsed=greet.parse('greet @a Hello World')
# or add it to a version to make it work everywherefrommcfunctionimportget_version, parse_commandversion=get_version() # latest versionversion.add_command(greet)
parsed=parse_command('greet @a Hello World')You can use the parse_mcfunction function to parse a mcfunction file.
You could parse each line with parse_command, but you'd need to ignore
comments and blank lines (so it doesn't crash). parse_mcfunction handles
blank lines and comments for you.
frommcfunctionimportparse_mcfunctionfrommcfunction.mcfunctionimportNoCommandcommands= [
'# summon enderdragon''summon minecraft:ender_dragon ~ ~ ~',
'',
'#summon wither', # both comment styles supported'summon minecraft:wither ~ ~ ~',
]
mcfunction=parse_mcfunction(commands)
# get the summon commands by simply accessing the listsummon_enderdragon=mcfunction.commands[1]
summon_wither=mcfunction.commands[4]
forcommandinmcfunction.commands:
# only print commands, not blank lines or commentsifnotisinstance(command, NoCommand):
print('command', command)
# you can access the commentprint(mcfunction.commands[0].comment.value)
# change it;mcfunction.commands[0].comment.value='summon sheep'summon_enderdragon.entity.name='sheep'# you can also change the stylemcfunction.commands[2].command='# 'This library currently supports 1.8 - 1.16.
When using a parse function (parse_command and parse_mcfunction) you can
specfiy which version's syntax you want (defaults to the latest version).
frommcfunctionimportparse_command, get_versionfrommcfunction.versions.mc_1_8.executeimportParsedExecuteCommandversion=get_version('1.8') # 1.8, 1.9, 1.10, ...# execute was reworked in 1.13 with totally new syntax, but# we can use the old 1.8 syntax with thiscommand=parse_command('execute @p ~ ~ ~ say 1.8 > all', version)
command: ParsedExecuteCommand# for type hintingNOTE: Note for type-hinting. If you're using e.g. 1.16 and a command which wasn't changed since 1.8, you have to use 1.8 as version when importing.
mcfunction.versions.mc_1_8.baninstead ofmcfunction.versions.mc_1_16.ban
This project does not use any external dependencies, except for development/testing.
pytest- pytest is used for testing the program, install it with
pip install pytest make testfor testing
- pytest is used for testing the program, install it with
flake8- flake8 is used for linting the program, install it with
pip install flake8 make lintfor linting
- flake8 is used for linting the program, install it with
coverage- coverage is used for generating test coverage, install it with
pip install coverage make coveragefor generating the test coverage (requirespytest)
- coverage is used for generating test coverage, install it with