找回密码
 立即注册

微信登录

只需一步,快速开始

QQ登录

只需一步,快速开始

[1.13-1.19]Minecraft-Python —— 支持Python脚本插件

像素搬运菌 2024-3-4 20:32:04 综合 阅读 296 来自 中国江苏无锡
服务器插件
中文名称:
英文名称: Minecraft-Python
插件来源: 转载
适用服务端: Spigot Paper 
插件类型: 综合
语言支持: 中文 英文 
适用版本: 1.13.x 1.14.x 1.15.x 1.16.x 1.17.x 1.18.x 1.19.x 
前置插件/mod: 无前置插件
下载地址: https://github.com/Macuyiko/minecraft-python
原贴地址: https://github.com/Macuyiko/minecraft-python

马上登录/注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
简介

这是一个Spigot插件,其能够使用库的形式将Bukkit API开放给Python使用。

与其他插件不同,它并没有将几个指令硬生生的硬编码进插件中。



解释器

插件的解释器基于Jython。这的好处是完整的Python解释器系统在JVM内部运行,但缺点是它只支持Python 2




指令

您可以通过telnet服务器、websocket服务器和聊天指令(/py、/pyload和/pyrestart)与Jython解释器交互。

/py <代码> 在Jython解释器上运行一行Python代码(每个玩家都有自己的解释器实例)。

在需要提供带有空格的缩进时,可以使用<代码>行开头的.(点)(Minecraft服务器通常忽略空格)。

/pyrestart 用于重新启动Jython解释器。

/pyload <文件> 取本地Python文件(在服务器上)并在Jython解释器中执行。




内置的Python模块mcapi.py提供了一些预定义的方便命令,可以在远程解释器中导入。

将.py文件放在python-plugins目录中时,这些文件在启动插件时会作为“插件”运行。

此解释器继续运行,可用于设置全局监听器。在一段时间的闲置后,解释器会被删除。




关于Python3

Jython目前只支持Python 2,而且似乎它会持续很长一段时间。
有各种Python 3 <-> JVM互操作项目可用,尽管这些项目似乎都没有像Jython那样在JVM实现上提供完整的Python的易用性。


Py4j很接近,早期的提交确实提供了一种使用此库与Minecraft交互的方法。

然而,Py4J实现严重依赖Python和JVM之间的回调,这些回调通过网络发送。

将此与许多线程杂耍和Spigt的内部线程模型相结合是令人生畏的。

该实现有效,但在尝试在Spigot服务器上执行大量操作时非常不稳定,所以我最终暂时将其从代码库中删除。

我(原作者)稍后可能会把这个重新添加到一个单独的分支中。



开始

从最新版本到最新版本,该插件的安装与任何其他Spigot插件一样。你至少需要Java 8。

在引导时,lib-common和python目录将自动创建。如果您想访问Python脚本中的其他Minecraft插件,他们的JAR文件可以复制到lib自定义目录。


例子
# Import some modules
from mcapi import *
from time import sleep
from random import randint

MY_NAME = "Macuyiko"

# Note: all code runs asynchronously by default. If you want to make world edits, Spigot
# forces you to execute these on a synchronised task. Most of the methods included in mcapi
# will take care of this automatically

# Set the time to sundawn
time(0)

# Zap the point where I'm looking at
bolt(lookingat(player(MY_NAME)))

# A small explosion instead
explosion(lookingat(player(MY_NAME)), power=2)

# Generate a tree (only works if there is room)
tree(lookingat(player(MY_NAME)))

# Spawn some particles
particle(lookingat(player(MY_NAME)))

# Spawn an entity (chicken by default)
spawn(lookingat(player(MY_NAME)))

# Fireworks
fireworks(lookingat(player(MY_NAME)))

# Let's create an exploding chicken spell

def exploding_chicken(player_name):
    yell("Creating an exploding chicken")
    chicken = spawn(lookingat(player(player_name)))
    for i in range(5,0,-1):
        yell("%s second(s) left..." % i)
        sleep(1)
    explosion(location(chicken), power=2)
        
        
# Try it!
exploding_chicken(MY_NAME)

# Now let's define a command for this spell
# Command functions take a special form func(caller, params)

@asynchronous()
def cmd_explode_spell(caller, params):
        exploding_chicken(caller.getName())

# Commands are executed synchronously by Spigot
# This means that all actions in exploding_chicken would use the state of the
# world as it was at the current server tick when executing the command,
# hence, we use the @asynchronous() decorator to force this function to be
# ran asynchronously, only synchronising every time a synchronous command is called

add_command('chickenspell', cmd_explode_spell)

# Try typing `/chickenspell` in Minecraft chat window
# Commands can be unregistered using
remove_command('chickenspell')

# Let's register another command to show of the asynchronous workings

@asynchronous()
def cmd_growme(caller, params):
    beginning = lookingat(player(caller.getName()))
    position = [beginning.x, beginning.y, beginning.z]
    for i in range(100):
        setblock(position) # <- will be synchronised
        position[randint(0,2)] += randint(-1,1)
        position[1] += +1
        sleep(0.05)

add_command('growme', cmd_growme)

# Now let's register an event
# These need a func(event) definition

from org.bukkit.event.block import BlockDamageEvent

# Almost all events execute synchronised, so again we force them to be asynchronous

@asynchronous()
def damage_evt(e):
    player = e.getPlayer()
    position = location(player)
    yell("I'll count to ten, get out!")
    for i in range(10):
        yell(str(i))
        sleep(1.0)
    explosion(position)

# A block will explode if the player damages it
listener = add_event_listener(BlockDamageEvent, damage_evt)

# Remove specific event hook
remove_event_listener(listener)

# Or all hooks
remove_event_listeners()
from mcapi import *
from time import sleep
from random import randint

from org.bukkit.event.player import PlayerJoinEvent

@asynchronous()
def join_event(e):
    player = e.getPlayer()
    player_location = location(player)
    player_location.y += 20
    yell("A chickeny hello to player %s" % (player.getName(),))
    for i in range(10):
        spawn(player_location)

listener = add_event_listener(PlayerJoinEvent, join_event)

(0)
像素搬运菌板块版主

帖子地址: 

发表回复

使用道具 举报