feat: add sync info and change function in blocks_tools

This commit is contained in:
2026-05-26 21:46:46 +08:00
parent 73f8c1f2be
commit 50f88f31f8
13 changed files with 274 additions and 34 deletions

View File

@@ -1,5 +1,5 @@
name = "air"
id = 0 id = 0
is_cross_plane = false
is_liquid = false is_liquid = false
is_passable = true is_passable = true
is_cross_plane = false name = 'air'

View File

@@ -1,5 +1,5 @@
name = "dirt"
id = 2 id = 2
is_cross_plane = false
is_liquid = false is_liquid = false
is_passable = false is_passable = false
is_cross_plane = false name = 'dirt'

View File

@@ -1,5 +1,5 @@
name = "grass"
id = 9 id = 9
is_cross_plane = true
is_liquid = false is_liquid = false
is_passable = true is_passable = true
is_cross_plane = true name = 'grass'

View File

@@ -1,5 +1,5 @@
name = "grass_block"
id = 1 id = 1
is_cross_plane = false
is_liquid = false is_liquid = false
is_passable = false is_passable = false
is_cross_plane = false name = 'grass_block'

View File

@@ -1,5 +1,5 @@
name = "leaf"
id = 6 id = 6
is_cross_plane = false
is_liquid = false is_liquid = false
is_passable = false is_passable = false
is_cross_plane = false name = 'leaf'

View File

@@ -1,5 +1,5 @@
name = "log"
id = 5 id = 5
is_cross_plane = false
is_liquid = false is_liquid = false
is_passable = false is_passable = false
is_cross_plane = false name = 'log'

View File

@@ -1,5 +1,5 @@
name = "sand"
id = 4 id = 4
is_cross_plane = false
is_liquid = false is_liquid = false
is_passable = false is_passable = false
is_cross_plane = false name = 'sand'

View File

@@ -1,5 +1,5 @@
name = "snowy_grass_block"
id = 8 id = 8
is_cross_plane = false
is_liquid = false is_liquid = false
is_passable = false is_passable = false
is_cross_plane = false name = 'snowy_grass_block'

View File

@@ -1,5 +1,5 @@
name = "stone"
id = 3 id = 3
is_cross_plane = false
is_liquid = false is_liquid = false
is_passable = false is_passable = false
is_cross_plane = false name = 'stone'

View File

@@ -1,5 +1,5 @@
name = "water"
id = 7 id = 7
is_cross_plane = false
is_liquid = true is_liquid = true
is_passable = false is_passable = false
is_cross_plane = false name = 'water'

View File

@@ -6,6 +6,7 @@ readme = "README.md"
requires-python = ">=3.14" requires-python = ">=3.14"
dependencies = [ dependencies = [
"loguru>=0.7.3", "loguru>=0.7.3",
"pytomlpp>=1.1.0",
] ]
[dependency-groups] [dependency-groups]

View File

@@ -1,47 +1,240 @@
import argparse import argparse
import sys import sys
import tomllib from functools import singledispatch
from pathlib import Path from pathlib import Path
from pprint import pprint
from typing import Any from typing import Any
import pytomlpp
from loguru import logger from loguru import logger
VERSION = "0.0.1" VERSION = "0.0.1"
DATA_PATH = "assets/data/block" DATA_PATH = "assets/data/block"
TEXTURE_PATH = "assets/texture/block" TEXTURE_PATH = "assets/texture/block"
work_path = Path(__file__).parent.parent
data_path = work_path / DATA_PATH
texture_path = work_path / TEXTURE_PATH
def show_data_list():
work_path = Path().parent def collect_blocks() -> list[dict[str, Any]]:
data_path = work_path / DATA_PATH
blocks: list[dict[str, Any]] = [] blocks: list[dict[str, Any]] = []
for block in data_path.rglob("*.toml"): for block in data_path.rglob("*.toml"):
if not block.is_file(): if not block.is_file():
continue continue
if block.name == "template.toml": if block.name == "template.toml":
continue continue
with open(block, "rb") as f:
blocks.append(tomllib.load(f))
blocks.sort(key=lambda x: x["id"])
blocks.append(pytomlpp.loads(block.read_text(encoding="utf-8")))
blocks.sort(key=lambda x: x["id"])
return blocks
def save_data(blocks: list[dict[str, Any]]):
for block in blocks:
block_path: Path = data_path / (block["name"] + ".toml")
if not block_path.is_file():
logger.error(f"Block: {block_path} is not Exists or a File")
continue
block_path.write_text(pytomlpp.dumps(block))
def sync_template_value():
blocks = collect_blocks()
template_path = data_path / "template.toml"
if not template_path.is_file():
logger.error("Template.toml is not Exists!")
return
template_block = pytomlpp.loads(template_path.read_text(encoding="utf-8"))
add_count = 0
for key, value in template_block.items():
for block in blocks:
if key not in block:
block[key] = value
add_count += 1
save_data(blocks)
logger.info(f"Synced {add_count} template fields to blocks")
@singledispatch
def show_data_info(arg: Any):
logger.error("No Match show_data_info")
@show_data_info.register(type(None))
def _(arg: None):
blocks = collect_blocks()
print("Please Input Block Name or Id, Input exit or e to Exit")
while True:
input_str = input("Name or Id: ")
try:
id = int(input_str)
if id >= len(blocks) or id < 0:
print(f"Id: {id} Not Find, Input e or exit to Exit")
continue
pprint(blocks[id])
except ValueError:
if input_str.lower() == "exit" or input_str.lower() == "e":
break
find = False
for block in blocks:
if block["name"] == input_str:
pprint(block)
find = True
break
if not find:
print(f"Name: {input_str} Not Find, Input e or exit to Exit")
@show_data_info.register(int)
def _(id: int):
blocks = collect_blocks()
if id >= len(blocks) or id < 0:
logger.error(f"ID: {id} is Not Invaild!")
return
pprint(blocks[id])
@show_data_info.register(str)
def _(name: str):
blocks = collect_blocks()
find = False
for block in blocks:
if block["name"] == name:
pprint(block)
find = True
break
if not find:
logger.error(f"Block Name: {name} Not Find")
def handle_change(block: dict[str, Any]) -> dict[str, Any]:
print("Please Input Block Key, Input exit or e to Exit")
while True:
key = input("Key: ")
if key.lower() == "exit" or key.lower() == "e":
break
if key not in block:
logger.error("The Key Is Not Exists!")
continue
value = input("Value: ")
if isinstance(block[key], str):
if value.lower() == "exit" or value.lower() == "e":
print(f"The Value Is {value}, Do You Want to Exit or Write (Y/N)")
ans = input()
if ans.lower() == "y":
break
elif ans.lower() != "n":
logger.error(f"Unknow {ans}")
continue
block[key] = value
elif isinstance(block[key], int):
try:
v = int(value)
block[key] = v
except ValueError:
logger.error("The Value Is Not A Int")
continue
elif isinstance(block[key], bool):
if value.lower() == "true":
block[key] = True
elif value.lower() == "false":
block[key] = False
else:
logger.error("The Value Is Not A Bool")
continue
elif isinstance(block[key], float):
try:
v = float(value)
block[key] = v
except ValueError:
logger.error("The Value Is Not A Float")
continue
else:
logger.error("Unkown Key Type")
continue
print("Change Success")
pprint(block)
return block
@singledispatch
def change_data(arg: Any):
logger.error("Not Match change")
@change_data.register(int)
def _(id: int):
blocks = collect_blocks()
if id >= len(blocks) or id < 0:
logger.error(f"ID: {id} is Invaild!")
return
pprint(blocks[id])
blocks[id] = handle_change(blocks[id])
save_data(blocks)
@change_data.register(str)
def _(name: str):
blocks = collect_blocks()
find = False
for i, block in enumerate(blocks):
if block["name"] == name:
pprint(block)
blocks[i] = handle_change(block)
save_data(blocks)
find = True
break
if not find:
logger.error(f"Block Name: {name} Not Find")
@change_data.register(type(None))
def _(arg: None):
blocks = collect_blocks()
print("Please Input Block Name or Id, Input exit or e to Exit")
while True:
input_str = input("Name or Id: ")
try:
id = int(input_str)
if id >= len(blocks) or id < 0:
print(f"Id: {id} Not Find, Input e or exit to Exit")
continue
pprint(blocks[id])
blocks[id] = handle_change(blocks[id])
save_data(blocks)
except ValueError:
if input_str.lower() == "exit" or input_str.lower() == "e":
break
find = False
for i, block in enumerate(blocks):
if block["name"] == input_str:
pprint(block)
blocks[i] = handle_change(block)
save_data(blocks)
find = True
break
if not find:
print(f"Name: {input_str} Not Find, Input e or exit to Exit")
def show_data_list():
blocks = collect_blocks()
for block in blocks: for block in blocks:
print(f"id: {block['id']} name: {block['name']}") print(f"id: {block['id']} name: {block['name']}")
def check_path(): def check_path():
work_path = Path().parent
logger.info(f"Work Path {work_path.resolve()}") logger.info(f"Work Path {work_path.resolve()}")
logger.info(f"Script Dir {sys.path[0]}") logger.info(f"Script Dir {sys.path[0]}")
data_path = work_path / DATA_PATH
if not data_path.exists(): if not data_path.exists():
logger.error(f"Blcoks Data Path {data_path} not Exists!") logger.error(f"Blocks Data Path {data_path} not Exists!")
else: else:
logger.info(f"Blocks Data Path {data_path}") logger.info(f"Blocks Data Path {data_path}")
texture_path = work_path / TEXTURE_PATH
if not texture_path.exists(): if not texture_path.exists():
logger.error(f"Blocks Texture Path {texture_path} not Exists!") logger.error(f"Blocks Texture Path {texture_path} not Exists!")
else: else:
@@ -56,6 +249,26 @@ def handle_args(args: argparse.Namespace):
check_path() check_path()
if args.list: if args.list:
show_data_list() show_data_list()
if args.sync:
sync_template_value()
if args.info:
if args.info == "EMPTY":
show_data_info(None)
else:
try:
id = int(args.info)
show_data_info(id)
except ValueError:
show_data_info(args.info)
if args.change:
if args.change == "EMPTY":
change_data(None)
else:
try:
id = int(args.change)
change_data(id)
except ValueError:
change_data(args.change)
def init_parser(parser: argparse.ArgumentParser): def init_parser(parser: argparse.ArgumentParser):
@@ -66,6 +279,22 @@ def init_parser(parser: argparse.ArgumentParser):
"--path", action="store_true", help="Check Blcoks Data and Texture Path" "--path", action="store_true", help="Check Blcoks Data and Texture Path"
) )
parser.add_argument("-l", "--list", action="store_true", help="Show Blocks List") parser.add_argument("-l", "--list", action="store_true", help="Show Blocks List")
parser.add_argument(
"-s",
"--sync",
action="store_true",
help="Sync Template.toml Value to Other Toml, Only New Value Will Add",
)
parser.add_argument(
"-i",
"--info",
nargs="?",
const="EMPTY",
help="Show Block Data, If Provide Id Will Print the Corresponding Blcok Data, You Can Input Id or Name",
)
parser.add_argument(
"-c", "--change", nargs="?", const="EMPTY", help="Change Block Data"
)
def main(): def main():

12
uv.lock generated
View File

@@ -17,6 +17,7 @@ version = "0.1.0"
source = { virtual = "." } source = { virtual = "." }
dependencies = [ dependencies = [
{ name = "loguru" }, { name = "loguru" },
{ name = "pytomlpp" },
] ]
[package.dev-dependencies] [package.dev-dependencies]
@@ -25,7 +26,10 @@ dev = [
] ]
[package.metadata] [package.metadata]
requires-dist = [{ name = "loguru", specifier = ">=0.7.3" }] requires-dist = [
{ name = "loguru", specifier = ">=0.7.3" },
{ name = "pytomlpp", specifier = ">=1.1.0" },
]
[package.metadata.requires-dev] [package.metadata.requires-dev]
dev = [{ name = "ruff", specifier = ">=0.15.14" }] dev = [{ name = "ruff", specifier = ">=0.15.14" }]
@@ -43,6 +47,12 @@ wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl", hash = "sha256:31a33c10c8e1e10422bfd431aeb5d351c7cf7fa671e3c4df004162264b28220c", size = 61595, upload-time = "2024-12-06T11:20:54.538Z" }, { url = "https://mirrors.ustc.edu.cn/pypi/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl", hash = "sha256:31a33c10c8e1e10422bfd431aeb5d351c7cf7fa671e3c4df004162264b28220c", size = 61595, upload-time = "2024-12-06T11:20:54.538Z" },
] ]
[[package]]
name = "pytomlpp"
version = "1.1.0"
source = { registry = "https://mirrors.ustc.edu.cn/pypi/simple" }
sdist = { url = "https://mirrors.ustc.edu.cn/pypi/packages/10/fe/50ca1ac0c1a932d3e71311baff531c0395e546ec0cd42bc8a8a88c36e00b/pytomlpp-1.1.0.tar.gz", hash = "sha256:61a0f73e7ba2fe8bba4e99ce6d2701491885850b53aad8f3e46d03c4b31e594d", size = 1323755, upload-time = "2025-11-29T20:52:09.582Z" }
[[package]] [[package]]
name = "ruff" name = "ruff"
version = "0.15.14" version = "0.15.14"