영상 캐시 기능 추가: 시작 시 미리받기 + 동적 재생 + FIFO 축출 + 주소 / 자동제거
- config 에 preload(미리받기 갯수)/keep(유지 갯수) 추가 - 시작 시 1..preload 캐시 미리받기, 재생 중에도 preload 개 앞까지 롤링 prefetch - 재생 시 캐시 있으면 video_N, 없으면 전체 URL 로 동적 선택(데이터팩 self-tracking) - keep 초과 시 가장 먼저 받은 캐시부터 삭제(FIFO) - namespace 끝 / 자동 제거(normalize) - command_block 한 tick 1회 발동 제약 회피: cache add/remove 직접 실행, clear 는 schedule Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
This commit is contained in:
@@ -38,4 +38,8 @@ function mq:quiz/stop_sound
|
|||||||
$scoreboard players set max_index main $(max_index)
|
$scoreboard players set max_index main $(max_index)
|
||||||
scoreboard players set init main 1
|
scoreboard players set init main 1
|
||||||
|
|
||||||
|
# 시작 시 1..preload 번 영상 캐시 미리받기. schedule 로 다음 tick(서버 소스)에
|
||||||
|
# 실행해 videoCache add 권한 보장 + max_index 설정 이후 동작 보장.
|
||||||
|
schedule function mq:videos/cache/preload 1t
|
||||||
|
|
||||||
dialog show @a mq:page1
|
dialog show @a mq:page1
|
||||||
|
|||||||
@@ -19,16 +19,22 @@ data modify storage mq:main audio set value {namespace: "musicquiz", source: "re
|
|||||||
data modify storage mq:main image set value {namespace: "mq", x: 2782, y: 88, z: 5979, facing: 2b}
|
data modify storage mq:main image set value {namespace: "mq", x: 2782, y: 88, z: 5979, facing: 2b}
|
||||||
|
|
||||||
# 정답 영상 — 모드의 영상 재생 관련
|
# 정답 영상 — 모드의 영상 재생 관련
|
||||||
# namespace — 영상 아이디를 제외한 주소 (마지막에 /는 없어야함)
|
# namespace — 영상 아이디를 제외한 주소 (마지막 / 는 자동으로 제거됨)
|
||||||
# x,y,z — 영상 블럭 좌표 (벽면 앞쪽 블록 위치)
|
# x,y,z — 영상 블럭 좌표 (벽면 앞쪽 블록 위치)
|
||||||
# w,h — 영상 가로세로 크키 (왼쪽아래 기준)
|
# w,h — 영상 가로세로 크키 (왼쪽아래 기준)
|
||||||
# facing — 영상이 바라보는 방향: south / west / north / east
|
# facing — 영상이 바라보는 방향: south / west / north / east
|
||||||
# sound — 영상 소리 설정 (0~100, 음소거: -1)
|
# sound — 영상 소리 설정 (0~100, 음소거: -1)
|
||||||
|
# preload — 게임 시작 시 미리 받아둘 영상 캐시 갯수 (1번부터 N번까지).
|
||||||
|
# 재생 중에도 항상 N개 앞까지 미리 받아둠. 0 이면 미리받기 끔(매번 URL 재생)
|
||||||
|
# keep — 캐시 유지 갯수(FIFO). 이 값을 넘기면 가장 먼저 받은 캐시부터 삭제.
|
||||||
|
# 메모리 관리용이므로 preload 보다 크거나 같게 설정 권장
|
||||||
data modify storage mq:main video set value { \
|
data modify storage mq:main video set value { \
|
||||||
namespace: "https://video.tkrmagid.kr/api/video/폴더1/폴더2", \
|
namespace: "https://video.tkrmagid.kr/api/video/폴더1/폴더2", \
|
||||||
cmd_x: 2769, cmd_y: 73, cmd_z: 5965, \
|
cmd_x: 2769, cmd_y: 73, cmd_z: 5965, \
|
||||||
x: 2731, y: 96, z: 6034, facing: "north", w: 25,h: 14, \
|
x: 2731, y: 96, z: 6034, facing: "north", w: 25,h: 14, \
|
||||||
sound: -1 \
|
sound: -1, \
|
||||||
|
preload: 5, \
|
||||||
|
keep: 10 \
|
||||||
}
|
}
|
||||||
|
|
||||||
# 곡 개수 max_index 는 init/songs.mcfunction 의 길이로 자동 계산됨
|
# 곡 개수 max_index 는 init/songs.mcfunction 의 길이로 자동 계산됨
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ data merge storage func:temp {}
|
|||||||
data merge storage mq:tmp {}
|
data merge storage mq:tmp {}
|
||||||
|
|
||||||
function mq:init/config
|
function mq:init/config
|
||||||
|
function mq:videos/normalize
|
||||||
function mq:init/songs
|
function mq:init/songs
|
||||||
function mq:init/buttons
|
function mq:init/buttons
|
||||||
function mq:init/triggers
|
function mq:init/triggers
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
data modify storage mq:tmp video set from storage mq:main video
|
# 재생 진행에 맞춰 항상 preload 개 앞까지 캐시를 채운다.
|
||||||
|
# 현재 index 에서 (preload-1) 만큼 앞선 영상을 받아두면 시작 시 preload(1..N)
|
||||||
|
# 와 합쳐져 N개 버퍼가 굴러간다.
|
||||||
|
execute store result score cache_preload func.temp run data get storage mq:main video.preload
|
||||||
|
execute if score cache_preload func.temp matches ..0 run return 0
|
||||||
|
|
||||||
scoreboard players operation cache_idx func.temp = index main
|
scoreboard players operation cache_target func.temp = index main
|
||||||
scoreboard players add cache_idx func.temp 1
|
scoreboard players operation cache_target func.temp += cache_preload func.temp
|
||||||
execute store result storage mq:tmp video.cache_num int 1 run scoreboard players get cache_idx func.temp
|
scoreboard players remove cache_target func.temp 1
|
||||||
|
execute if score cache_target func.temp > max_index main run return 0
|
||||||
|
|
||||||
execute store result storage mq:tmp video.num int 1 run scoreboard players get index main
|
function mq:videos/cache/add_one
|
||||||
data modify storage mq:tmp video.cmd set value "cache"
|
|
||||||
function mq:videos/macro/cmd with storage mq:tmp video
|
|
||||||
|
|||||||
4
music_quiz/data/mq/function/videos/cache/add_one.mcfunction
vendored
Normal file
4
music_quiz/data/mq/function/videos/cache/add_one.mcfunction
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# cache_target(func.temp) 번 영상을 캐시에 추가. 매크로로 넘겨 등록/추적/축출.
|
||||||
|
data modify storage mq:tmp video set from storage mq:main video
|
||||||
|
execute store result storage mq:tmp video.num int 1 run scoreboard players get cache_target func.temp
|
||||||
|
function mq:videos/cache/macro/add_one with storage mq:tmp video
|
||||||
@@ -1 +1,5 @@
|
|||||||
function mq:videos/macro/custom {cmd: "videoCache clear"}
|
# 추적 목록을 비우고, 다음 tick 에 서버 소스로 전체 캐시 wipe.
|
||||||
|
# (videoCache clear 를 호출자 소스에서 바로 실행하면 player/비OP 소스일 때
|
||||||
|
# 권한 문제가 날 수 있어 schedule 로 서버 소스 보장.)
|
||||||
|
data modify storage mq:main video.cached set value []
|
||||||
|
schedule function mq:videos/cache/clear_run 1t
|
||||||
|
|||||||
1
music_quiz/data/mq/function/videos/cache/clear_run.mcfunction
vendored
Normal file
1
music_quiz/data/mq/function/videos/cache/clear_run.mcfunction
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
videoCache clear
|
||||||
4
music_quiz/data/mq/function/videos/cache/evict.mcfunction
vendored
Normal file
4
music_quiz/data/mq/function/videos/cache/evict.mcfunction
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# 캐시 갯수가 keep 을 넘으면 가장 먼저 받은 것부터(FIFO) 삭제.
|
||||||
|
execute store result score cache_len func.temp run data get storage mq:main video.cached
|
||||||
|
execute store result score cache_keep func.temp run data get storage mq:main video.keep
|
||||||
|
execute if score cache_len func.temp > cache_keep func.temp run function mq:videos/cache/evict_one
|
||||||
5
music_quiz/data/mq/function/videos/cache/evict_one.mcfunction
vendored
Normal file
5
music_quiz/data/mq/function/videos/cache/evict_one.mcfunction
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
execute store result storage mq:tmp evict_num int 1 run data get storage mq:main video.cached[0].i
|
||||||
|
function mq:videos/cache/macro/evict_one with storage mq:tmp
|
||||||
|
data remove storage mq:main video.cached[0]
|
||||||
|
# keep 보다 여러 개 초과해 있을 수 있으니 재귀로 다시 검사.
|
||||||
|
function mq:videos/cache/evict
|
||||||
7
music_quiz/data/mq/function/videos/cache/macro/add_one.mcfunction
vendored
Normal file
7
music_quiz/data/mq/function/videos/cache/macro/add_one.mcfunction
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# 이미 받은 영상이면(추적 목록에 {i:num} 존재) 건너뜀.
|
||||||
|
$execute if data storage mq:main video.cached[{i:$(num)}] run return 0
|
||||||
|
# videoCache add 는 서버 소스(또는 OP)에서 직접 실행. preload/select 모두 서버
|
||||||
|
# 소스이므로 command_block 우회 없이 바로 호출 가능.
|
||||||
|
$videoCache add video_$(num) $(namespace)/$(num)
|
||||||
|
$data modify storage mq:main video.cached append value {i:$(num)}
|
||||||
|
function mq:videos/cache/evict
|
||||||
1
music_quiz/data/mq/function/videos/cache/macro/evict_one.mcfunction
vendored
Normal file
1
music_quiz/data/mq/function/videos/cache/macro/evict_one.mcfunction
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
$videoCache remove video_$(evict_num)
|
||||||
5
music_quiz/data/mq/function/videos/cache/preload.mcfunction
vendored
Normal file
5
music_quiz/data/mq/function/videos/cache/preload.mcfunction
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# 게임 시작 시 1번부터 preload 번까지 캐시를 미리 받는다 (max_index 로 상한).
|
||||||
|
scoreboard players set cache_i func.temp 1
|
||||||
|
execute store result score cache_max func.temp run data get storage mq:main video.preload
|
||||||
|
execute if score cache_max func.temp > max_index main run scoreboard players operation cache_max func.temp = max_index main
|
||||||
|
function mq:videos/cache/preload_loop
|
||||||
5
music_quiz/data/mq/function/videos/cache/preload_loop.mcfunction
vendored
Normal file
5
music_quiz/data/mq/function/videos/cache/preload_loop.mcfunction
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
execute if score cache_i func.temp > cache_max func.temp run return 0
|
||||||
|
scoreboard players operation cache_target func.temp = cache_i func.temp
|
||||||
|
function mq:videos/cache/add_one
|
||||||
|
scoreboard players add cache_i func.temp 1
|
||||||
|
function mq:videos/cache/preload_loop
|
||||||
@@ -2,15 +2,11 @@ $execute if data storage mq:tmp {video:{cmd:"delete"}} run setblock $(cmd_x) $(c
|
|||||||
Command:"videoDelete $(x) $(y) $(z)", \
|
Command:"videoDelete $(x) $(y) $(z)", \
|
||||||
auto:0b \
|
auto:0b \
|
||||||
}
|
}
|
||||||
$execute if data storage mq:tmp {video:{cmd:"num"}} run setblock $(cmd_x) $(cmd_y) $(cmd_z) minecraft:command_block[conditional=false,facing=up]{ \
|
$execute if data storage mq:tmp {video:{cmd:"play"}} run setblock $(cmd_x) $(cmd_y) $(cmd_z) minecraft:command_block[conditional=false,facing=up]{ \
|
||||||
Command:"videoPlace $(x) $(y) $(z) $(facing) $(w) $(h) $(sound) video_$(num)", \
|
Command:"videoPlace $(x) $(y) $(z) $(facing) $(w) $(h) $(sound) $(src)", \
|
||||||
auto:0b \
|
auto:0b \
|
||||||
}
|
}
|
||||||
$execute if data storage mq:tmp {video:{cmd:"cache"}} run setblock $(cmd_x) $(cmd_y) $(cmd_z) minecraft:command_block[conditional=false,facing=up]{ \
|
$execute if data storage mq:tmp {video:{cmd:"custom"}} run setblock $(cmd_x) $(cmd_y) $(cmd_z) minecraft:command_block[conditional=false,facing=up]{ \
|
||||||
Command:"videoCache add video_$(num) $(namespace)/$(cache_num)", \
|
|
||||||
auto:0b \
|
|
||||||
}
|
|
||||||
$execute if data storage mq:tmp {video:{cmd:"cmd"}} run setblock $(cmd_x) $(cmd_y) $(cmd_z) minecraft:command_block[conditional=false,facing=up]{ \
|
|
||||||
Command:"$(cmd_value)", \
|
Command:"$(cmd_value)", \
|
||||||
auto:0b \
|
auto:0b \
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
function mq:videos/clear
|
|
||||||
data modify storage mq:tmp video set from storage mq:main video
|
|
||||||
execute store result storage mq:tmp video.num int 1 run scoreboard players get index main
|
|
||||||
data modify storage mq:tmp video.cmd set value "custom"
|
|
||||||
$data modify storage mq:tmp video.cmd_value set value "$(cmd)"
|
|
||||||
function mq:videos/macro/cmd with storage mq:tmp video
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# mq:tmp video.src 를 결정한다.
|
||||||
|
# - 기본: 전체 URL "<namespace>/<num>"
|
||||||
|
# - mq:main video.cached 목록에 {i:num} 이 있으면(=videoCache add 로 등록됨)
|
||||||
|
# 등록 이름 "video_<num>" 사용 → 모드가 서버 config 에서 URL 로 resolve.
|
||||||
|
# cached 목록은 데이터팩이 videoCache add/remove 와 1:1 로 직접 추적하므로
|
||||||
|
# 모드에 캐시 존재 여부를 묻지 않고도 정확하다.
|
||||||
|
$data modify storage mq:tmp video.src set value "$(namespace)/$(num)"
|
||||||
|
$execute if data storage mq:main video.cached[{i:$(num)}] run data modify storage mq:tmp video.src set value "video_$(num)"
|
||||||
7
music_quiz/data/mq/function/videos/normalize.mcfunction
Normal file
7
music_quiz/data/mq/function/videos/normalize.mcfunction
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# namespace 끝에 / 가 붙어 있으면 제거 (config 오타 방어).
|
||||||
|
# string 소스 마지막 글자만 떼서 비교 후, 맞으면 마지막 글자를 잘라낸다.
|
||||||
|
data modify storage mq:tmp ns_last set string storage mq:main video.namespace -1
|
||||||
|
execute if data storage mq:tmp {ns_last:"/"} run data modify storage mq:main video.namespace set string storage mq:main video.namespace 0 -1
|
||||||
|
|
||||||
|
# 캐시 추적 목록 초기화 (videoCache add/remove 와 1:1 로 관리되는 {i:N} 리스트)
|
||||||
|
data modify storage mq:main video.cached set value []
|
||||||
@@ -1,5 +1,10 @@
|
|||||||
function mq:videos/clear
|
# 정답 영상 재생. videoPlace 는 같은 앵커 좌표를 덮어쓰므로 별도 clear 불필요
|
||||||
|
# (clear + place 를 한 tick 에 하면 command_block 이 한 번만 켜져 place 가 씹힘).
|
||||||
data modify storage mq:tmp video set from storage mq:main video
|
data modify storage mq:tmp video set from storage mq:main video
|
||||||
execute store result storage mq:tmp video.num int 1 run scoreboard players get index main
|
execute store result storage mq:tmp video.num int 1 run scoreboard players get index main
|
||||||
data modify storage mq:tmp video.cmd set value "num"
|
|
||||||
|
# 캐시가 있으면 video_N(등록된 이름), 없으면 전체 URL 로 src 결정
|
||||||
|
function mq:videos/macro/resolve_src with storage mq:tmp video
|
||||||
|
|
||||||
|
data modify storage mq:tmp video.cmd set value "play"
|
||||||
function mq:videos/macro/cmd with storage mq:tmp video
|
function mq:videos/macro/cmd with storage mq:tmp video
|
||||||
|
|||||||
Reference in New Issue
Block a user