/
mc-item-scanner.py
144 lines (117 loc) · 4.89 KB
/
mc-item-scanner.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import nbtlib
import anvil
from anvil.errors import ChunkNotFound
import os
import argparse
import csv
import time
aparser = argparse.ArgumentParser(description=r"path of \world")
aparser.add_argument('-o', '--outdirectory', default=r'.\\')
aparser.add_argument('-w', '--worlddirectory', default=r'.\\')
args = aparser.parse_args()
PATH_OUTDIR = args.outdirectory
PATH_WORLD = args.worlddirectory
item_record: dict = {}
def count_item(item_id, item_count: int):
item_id: str = str(item_id)
if item_id not in item_record:
item_record[item_id] = 0
item_record[item_id] += item_count
def region_search(region_file):
def search_shulker_box_item(shulker_box):
try:
if "Items" not in shulker_box["tag"]["BlockEntityTag"]:
return
for item in shulker_box["tag"]["BlockEntityTag"]["Items"]:
count_item(item["id"], int(str(item["Count"])))
# print(item["id"], " ", item["Count"])
except KeyError as k:
print(f"KeyError: {k}")
print(target_region)
print(shulker_box)
target_region = anvil.Region.from_file(region_file)
try:
for i in range(0, 32):
for j in range(0, 32):
try:
chunk = anvil.Chunk.from_region(target_region, i, j)
if chunk.tile_entities:
te = chunk.tile_entities
for k in te:
if "Items" not in k:
continue
for a in k["Items"]:
count_item(a["id"], int(str(a["Count"])))
# print(a["id"], " ", a["Count"])
if str(a["id"]).endswith("shulker_box") and "tag" in a:
search_shulker_box_item(a)
except ChunkNotFound:
pass
except IndexError as e:
print(f"{e}, when searching region {region_file}")
def player_inventory_search(data_file):
def search_shulker_box_item(shulker_box):
try:
if "Items" not in shulker_box["tag"]["BlockEntityTag"]:
return
for item in shulker_box["tag"]["BlockEntityTag"]["Items"]:
count_item(item["id"], int(item["Count"]))
# print(item["id"], " ", item["Count"])
except KeyError as e:
print(f"KeyError: {e}")
print(data_file)
print(shulker_box)
target_file = nbtlib.load(data_file)
for i in target_file["Inventory"]:
count_item(i["id"], int(i["Count"]))
# print(i["id"], " ", int(i["Count"]))
if str(i["id"]).endswith("shulker_box") and "tag" in i:
search_shulker_box_item(i)
for i in target_file["EnderItems"]:
count_item(i["id"], int(i["Count"]))
# print(i["id"], " ", int(i["Count"]))
if str(i["id"]).endswith("shulker_box") and "tag" in i:
search_shulker_box_item(i)
def main():
start_time = time.time()
if not os.path.isdir(PATH_OUTDIR):
raise NotADirectoryError("the outdirectory specified is not a directory")
if "level.dat" not in os.listdir(PATH_WORLD):
raise FileNotFoundError("file: level.dat cannot be found in the world directory!")
try:
print(r"searching \playerdata")
for f in os.listdir(fr"{PATH_WORLD}\playerdata"):
if f.endswith(".dat"):
player_inventory_search(fr"{PATH_WORLD}\playerdata\{f}")
except FileNotFoundError:
print(r"directory: \playerdata cannot be found in the world directory")
try:
print(r"searching \region")
for f in os.listdir(fr"{PATH_WORLD}\region"):
if f.endswith(".mca"):
region_search(fr"{PATH_WORLD}\region\{f}")
except FileNotFoundError:
print(r"directory: \region cannot be found in the world directory")
try:
print(r"searching \DIM1\region")
for f in os.listdir(fr"{PATH_WORLD}\DIM1\region"):
if f.endswith(".mca"):
region_search(fr"{PATH_WORLD}\DIM1\region\{f}")
except FileNotFoundError:
print(r"directory: \DIM1\region cannot be found in the world directory")
try:
print(r"searching \DIM-1\region")
for f in os.listdir(fr"{PATH_WORLD}\DIM-1\region"):
if f.endswith(".mca"):
region_search(fr"{PATH_WORLD}\DIM-1\region\{f}")
except FileNotFoundError:
print(r"directory: \DIM-1\region cannot be found in the world directory")
# print(item_record)
with open(fr'{PATH_OUTDIR}\results.csv', 'w', encoding='utf8', newline='') as out:
writer = csv.writer(out)
writer.writerow(["item", "count"])
for i in item_record.items():
writer.writerow(list(i))
print(f"completed! Using {time.time() - start_time} seconds")
if __name__ == '__main__':
main()