2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Minecraft CommandAdvent Calendar 2024

Day 14

バニラマイクラ鯖で外部とデータをやり取りしてみる

Last updated at Posted at 2024-12-14

Minecraft Command Advent Calendar 2024 14日目の記事です

はじめに

バニラ鯖でも外部通信、したくないですか?
今回は外部と通信する方法をいくつかまとめたので解説していきます

基本的に外部ツールが必須となっています

早見表

方法 双方向性 リアルタイム性 シングルプレイ 外部ツール 転送可能データ量 備考
RCON 必要 多い ログがかなり荒れる
チャットログ 必要 多い ゲーム内チャットに表示される
名前付きモブ 必要 多い ログが若干荒れる
nbtファイル 必要 とても多い
スキンデータ 不要 とても少ない

解説

RCON

バニラ鯖で通信すると言えばこれ。

使い方

server.propertiesenable-rcon=trueに設定、サーバーアドレスとrcon.passwordrcon.portに指定した値を接続ツール等に入れることで接続できる

コマンドが実行できるため基本的に何でもできる
ループ処理でリアルタイムに値を取得すると言ったことが可能
ただしtickを超える頻度でのアクセスを行った際の挙動は不明

実装例

Pythonのmcrconを使用

コード

from mcrcon import MCRcon

with MCRcon("127.0.0.1", "test") as mcr:
    resp = mcr.command("/scoreboard players get #data data")
    print(resp)

レスポンス

#data has 1 [data]

チャットログ

使い方

sayコマンド等のチャットログによる出力を利用

実装例

コード

送信用function

# データ送信用のモブを召喚
  summon minecraft:marker 0 0 0 {Tags:["message"],CustomName:'"#message"',NoAI:1b,Silent:1b}

# マクロ呼び出し
  execute positioned 0 0 0 as @n[type=marker,tag=message] run function message:say/macro with storage message

# kill
  execute positioned 0 0 0 run kill @n[type=minecraft:marker,tag=message,distance=..0.1]

マクロ

$say $(data)

ログ読み取り(python)

import os
import re

current_line = ""
while True:
  # ログのリアルタイム読み取り
  with open('logs/latest.log', 'rb') as f:
      try:  # catch OSError in case of a one line file
          f.seek(-2, os.SEEK_END)
          while f.read(1) != b'\n':
              f.seek(-2, os.SEEK_CUR)
      except OSError:
          f.seek(0)
      last_line = f.readline().decode().rstrip("\n")
  # 最終行が更新されていたら
  if last_line != current_line:
    # 正規表現で名前付きMOBの死亡メッセージを抽出
    match_line = re.search(r"(?<=\[\d\d:\d\d:\d\d] \[Server thread/INFO\]: \[Not Secure\] \[\#message\] ).*(?=)", last_line)
    if match_line:
      print(match_line.group(0))
  # 現在行を更新
  current_line = last_line

実行例

/data modify storage minecraft:message data set value {"test":[1,2,3,4]}
/function message:say

レスポンス

{test:[1,2,3,4]}

名前付きモブ

使い方

名前付きのモブをkillした際にログとして出力される挙動を利用
それなりに長めのデータも出力できる

実装例

コード

送信用function
※0 0 0に看板を設置します

# データ格納用のモブを召喚
  summon minecraft:allay 0 0 0 {Tags:["message"],CustomName:'""',NoAI:1b,Silent:1b}

# 一旦看板へデータを書き込む
  setblock 0 0 0 air
  setblock 0 0 0 oak_sign{front_text:{messages:['{"storage": "message","nbt":"data"}','""','""','""']}}

# モブのCustomNameへデータを代入
  execute positioned 0 0 0 run data modify entity @n[type=allay,tag=message,distance=..0.1] CustomName set from block 0 0 0 front_text.messages[0]
  # データの2重出力対策
  execute positioned 0 0 0 run damage @n[type=minecraft:allay,tag=message,distance=..0.1] 9999 message:nolog

# 看板を撤去
  setblock 0 0 0 air

ダメージタイプ

{
  "message_id": " ",
  "exhaustion": 0,
  "scaling": "never"
}

ログの読み取り(python)

import os
import re

current_line = ""
while True:
  # ログのリアルタイム読み取り
  with open('logs/latest.log', 'rb') as f:
      try:  # catch OSError in case of a one line file
          f.seek(-2, os.SEEK_END)
          while f.read(1) != b'\n':
              f.seek(-2, os.SEEK_CUR)
      except OSError:
          f.seek(0)
      last_line = f.readline().decode().rstrip("\n")
  # 最終行が更新されていたら
  if last_line != current_line:
    # 正規表現で名前付きMOBの死亡メッセージを抽出
    match_line = re.search(r"(?<=\[\d\d:\d\d:\d\d] \[Server thread/INFO\]: Named entity ...\[').*(?='/\d*. l\='ServerLevel\[.*\]', x\=\d*.\d*, y\=\d*.\d*, z\=\d*.\d*\] died: death.attack. )", last_line)
    if match_line:
      print(match_line.group(0))
  # 現在行を更新
  current_line = last_line

実行例

/data modify storage minecraft:message data set value {"test":[1,2,3,4]}
/function message:send

レスポンス

{test:[1,2,3,4]}

NBTファイル

使い方

ワールドデータ内にあるscoreboard.datcommand_storage_*.datを外部から読み込んで値を取得
ワールドを閉じるかsave-allを実行するとファイルが更新される
pythonであればNBTのようなライブラリで読み書きができる。

スキンデータ

使い方

プレイヤーのスキンデータを利用したデータの取得

まとめ

現状、RCONとログの読み取りによる送受信が最適解と思われる

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?