mcapibridge 0.1.3__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcapibridge
3
- Version: 0.1.3
3
+ Version: 0.2.0
4
4
  Summary: Python libary for MCAPIBridge
5
5
  Author: TaotianZhufang
6
6
  License: MIT License
@@ -145,6 +145,12 @@ Modifies the NBT data of a block entity (Tile Entity).
145
145
  * **nbt_string**: Valid SNBT string.
146
146
 
147
147
 
148
+ ---
149
+
150
+ ### Audio
151
+
152
+ #### [Audio Doc](https://github.com/TaotianZhufang/MCAPIBridge/blob/main/Bridges/Python/PyAudio.MD)
153
+
148
154
  ---
149
155
 
150
156
  ### Info
@@ -113,6 +113,12 @@ Modifies the NBT data of a block entity (Tile Entity).
113
113
  * **nbt_string**: Valid SNBT string.
114
114
 
115
115
 
116
+ ---
117
+
118
+ ### Audio
119
+
120
+ #### [Audio Doc](https://github.com/TaotianZhufang/MCAPIBridge/blob/main/Bridges/Python/PyAudio.MD)
121
+
116
122
  ---
117
123
 
118
124
  ### Info
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "mcapibridge"
7
- version = "0.1.3"
8
- description = "Python libary for MCAPIBridge"
7
+ version = "0.2.0"
8
+ description ="Python libary for MCAPIBridge"
9
9
  requires-python = ">=3.7"
10
10
  license = { file = "LICENSE" }
11
11
  readme = "README.MD"
@@ -1,6 +1,104 @@
1
1
  import socket
2
2
  import math
3
3
  import time
4
+ import base64
5
+ import wave
6
+ import struct
7
+
8
+ class AudioManager:
9
+ def __init__(self, mc):
10
+ self.mc = mc
11
+
12
+ def load_wav(self, target, audio_id, filepath):
13
+ with wave.open(filepath, 'rb') as wav:
14
+ channels = wav.getnchannels()
15
+ sample_width = wav.getsampwidth()
16
+ sample_rate = wav.getframerate()
17
+ frames = wav.readframes(wav.getnframes())
18
+
19
+ if channels == 2:
20
+ samples = struct.unpack(f'<{len(frames)//2}h', frames)
21
+ mono_samples = []
22
+ for i in range(0, len(samples), 2):
23
+ mono_samples.append((samples[i] + samples[i+1]) // 2)
24
+ frames = struct.pack(f'<{len(mono_samples)}h', *mono_samples)
25
+
26
+ if sample_width == 1:
27
+ samples = struct.unpack(f'{len(frames)}B', frames)
28
+ samples = [(s - 128) * 256 for s in samples]
29
+ frames = struct.pack(f'<{len(samples)}h', *samples)
30
+
31
+ b64_data = base64.b64encode(frames).decode('ascii')
32
+
33
+ chunk_size = 40000
34
+ chunks = [b64_data[i:i + chunk_size] for i in range(0, len(b64_data), chunk_size)]
35
+
36
+ for i, chunk in enumerate(chunks):
37
+ if i == 0:
38
+ self.mc._send(f"audio.load({target},{audio_id},{sample_rate},{chunk})")
39
+ else:
40
+ self.mc._send(f"audio.stream({target},{audio_id},{sample_rate},{chunk})")
41
+ time.sleep(0.02)
42
+
43
+ self.mc._send(f"audio.finishLoad({target},{audio_id})")
44
+
45
+ print(f"[Audio] Loaded {filepath}: {len(frames)} bytes, {sample_rate}Hz")
46
+
47
+ def load_raw(self, target, audio_id, pcm_data, sample_rate=44100):
48
+ b64_data = base64.b64encode(pcm_data).decode('ascii')
49
+
50
+ chunk_size = 40000
51
+ chunks = [b64_data[i:i + chunk_size] for i in range(0, len(b64_data), chunk_size)]
52
+
53
+ for i, chunk in enumerate(chunks):
54
+ if i == 0:
55
+ self.mc._send(f"audio.load({target},{audio_id},{sample_rate},{chunk})")
56
+ else:
57
+ self.mc._send(f"audio.stream({target},{audio_id},{sample_rate},{chunk})")
58
+ time.sleep(0.02)
59
+
60
+ self.mc._send(f"audio.finishLoad({target},{audio_id})")
61
+
62
+ def play(self, target, audio_id, volume=1.0, loop=False):
63
+ loop_str = "true" if loop else "false"
64
+ self.mc._send(f"audio.play({target},{audio_id},{volume},{loop_str})")
65
+
66
+ def play_at(self, audio_id, x, y, z, radius=32, volume=1.0):
67
+ self.mc._send(f"audio.playAt({audio_id},{x},{y},{z},{radius},{volume})")
68
+
69
+ def play_3d(self, target, audio_id, x, y, z, volume=1.0, rolloff=1.0):
70
+ self.mc._send(f"audio.play3d({target},{audio_id},{x},{y},{z},{volume},{rolloff})")
71
+
72
+ def pause(self, target, audio_id):
73
+ self.mc._send(f"audio.pause({target},{audio_id})")
74
+
75
+ def stop(self, target, audio_id):
76
+ self.mc._send(f"audio.stop({target},{audio_id})")
77
+
78
+ def unload(self, target, audio_id):
79
+ self.mc._send(f"audio.unload({target},{audio_id})")
80
+
81
+ def set_volume(self, target, audio_id, volume):
82
+ """(0.0 - 1.0)"""
83
+ self.mc._send(f"audio.volume({target},{audio_id},{volume})")
84
+
85
+ def generate_tone(self, target, audio_id, frequency=440, duration=1.0, sample_rate=44100):
86
+ import math
87
+
88
+ num_samples = int(sample_rate * duration)
89
+ samples = []
90
+
91
+ for i in range(num_samples):
92
+ t = i / sample_rate
93
+ value = int(32767 * math.sin(2 * math.pi * frequency * t))
94
+ samples.append(value)
95
+
96
+ pcm_data = struct.pack(f'<{len(samples)}h', *samples)
97
+ self.load_raw(target, audio_id, pcm_data, sample_rate)
98
+
99
+ def set_position(self, target, audio_id, x, y, z):
100
+ self.mc._send(f"audio.position({target},{audio_id},{x},{y},{z})")
101
+
4
102
 
5
103
  class Vec3:
6
104
  def __init__(self, x, y, z):
@@ -54,6 +152,7 @@ class Minecraft:
54
152
  self.file_reader = None
55
153
  self.connected = False
56
154
  self._connect()
155
+ self.audio = AudioManager(self)
57
156
 
58
157
  def _connect(self):
59
158
  try:
@@ -353,3 +452,20 @@ class Minecraft:
353
452
  cmd = f"block.setNbt({int(x)},{int(y)},{int(z)},{nbt_string})"
354
453
  if dimension: cmd += f",{dimension}"
355
454
  self._send(cmd)
455
+
456
+ def drawHandMap(self, pixels, target=None):
457
+ """
458
+ 绘制指定玩家手中的地图
459
+ """
460
+ CHUNK_SIZE = 1024
461
+ for i in range(0, len(pixels), CHUNK_SIZE):
462
+ chunk = pixels[i : i + CHUNK_SIZE]
463
+ data_str = ",".join(map(str, chunk))
464
+
465
+ cmd = f"map.drawHand({i},{data_str})"
466
+ if target:
467
+ cmd += f",{target}"
468
+
469
+ self._send(cmd)
470
+ time.sleep(0.01)
471
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcapibridge
3
- Version: 0.1.3
3
+ Version: 0.2.0
4
4
  Summary: Python libary for MCAPIBridge
5
5
  Author: TaotianZhufang
6
6
  License: MIT License
@@ -145,6 +145,12 @@ Modifies the NBT data of a block entity (Tile Entity).
145
145
  * **nbt_string**: Valid SNBT string.
146
146
 
147
147
 
148
+ ---
149
+
150
+ ### Audio
151
+
152
+ #### [Audio Doc](https://github.com/TaotianZhufang/MCAPIBridge/blob/main/Bridges/Python/PyAudio.MD)
153
+
148
154
  ---
149
155
 
150
156
  ### Info
File without changes
File without changes