Skip to content

Commit 618a393

Browse files
authored
Merge pull request #61 from GregTaoo/dev
Dev 1.4.1
2 parents bcb28b0 + 1a9190e commit 618a393

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+853
-180
lines changed

README.md

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
-----------------------------
1212

1313

14-
**Wiki 基准模组版本:1.3.8**
14+
**Wiki 基准模组版本:1.4.1**
1515

16-
目前已知支持版本:1.21.5, 1.21.4, 1.21.1, 1.20.6, 1.20.1, 1.19.4, 1.18.2, 1.17.1, 1.16.5,其余版本未经测试
16+
目前已知支持版本:1.21.7, 1.21.6, 1.21.5, 1.21.4, 1.21.1, 1.21, 1.20.6, 1.20.1, 1.19.4, 1.18.2, 1.17.1, 1.16.5,其余版本未经测试
1717

1818
### 安全提醒!
1919

@@ -64,6 +64,7 @@
6464

6565
`export-as-playlist`: 导出当前播放队列为服务端预设歌单格式 `JSON`(详见 服务端预设歌单)
6666

67+
`clean-cache`: 删除客户端 `Concerto/cache` 文件夹下所有文件(包括cookie)
6768

6869
2. `/concerto-server`(服务端指令,仅限管理员)
6970

@@ -79,12 +80,18 @@
7980

8081
`reload-cookie`: 重新加载所有cookie文件
8182

83+
`clean-cache`: 删除服务端 `Concerto/cache` 文件夹下所有文件(包括cookie)
84+
8285
`fetch-radios`: 技术性指令,同步服务端预设歌单到本地(允许普通用户使用)
8386

8487
`agent reset`: 重新加载服务端歌曲点播队列
8588

8689
`agent cut`: 强制让服务端点播队列播放下一首/切歌
8790

91+
`agent stop`: 停止点播歌曲的播放(注意:当前歌曲会被直接切掉)
92+
93+
`agent start`: 继续点播歌曲的播放(注意:从下一首开始)
94+
8895

8996
3. `/sharemusic`(客户端指令,服务端不安装 Concerto 也可使用,非音乐室功能)
9097

@@ -105,7 +112,7 @@
105112

106113
`join [UUID]`: 加入编号为 `[UUID]` 的音乐室
107114

108-
`quit`: 退出当前音乐室
115+
`quit`: 退出当前音乐室(或者点播室)
109116

110117
`members`: 显示当前所在音乐室的成员
111118

@@ -131,13 +138,21 @@
131138
- 单击选中音乐,再点击详情按钮查看音乐具体信息(内有**服务器点歌**按钮)
132139
- 可将多个文件/文件夹拖入 播放队列管理界面/添加音乐界面 进行添加
133140

141+
142+
### 本地预设歌单
143+
144+
- 使用 `/concerto export-as-playlist` 或歌单详情页面按钮导出歌单
145+
- 导出的 `JSON` 文件已经被放置于 `Concerto/local_playlists` 文件夹下
146+
- 可用 `/concerto reload` 重新加载最新添加的预设歌单
147+
- 可在 Concerto 主菜单里看到本地预设歌单的入口
148+
134149
### 服务端预设歌单
135150

136151
- 使用 `/concerto export-as-playlist` 或歌单详情页面按钮导出歌单
137-
- 将导出的 `JSON` 文件放置于 `Concerto/preset_radios` 文件夹下
152+
- 将导出的 `JSON` 文件复制并放置于 `Concerto/preset_radios` 文件夹下(默认是导出到本地的文件夹,`Concerto/local_playlists`
138153
- 若文件名为 `music_agent.json` 将作为音乐点播室空闲时候的歌单
139154
- 可用 `/concerto-server reload` 重新加载最新添加的预设歌单
140-
- 玩家可在 Concerto 主菜单里看到服务端预设歌单的入口
155+
- 服务器玩家可在 Concerto 主菜单里看到服务端预设歌单的入口
141156

142157
### 服务端配置文件
143158

@@ -225,19 +240,28 @@
225240

226241
即网易云音乐和QQ音乐,不含本地资源、其他网络资源
227242

243+
### 关于直接输入Cookie的登录方式
244+
245+
- 方法1: 打开对应网站登录后,电脑浏览器点按 F12 打开开发者面板的网络面板 (Network),刷新页面,点击第一个条目,往下滑动找到并复制所有Cookie
246+
- 方法2(推荐): 使用 Cookie-Editor 浏览器插件
247+
228248
### Q & A
229249

230250
- Q: 网易云音乐用密码或验证码登录时出现“当前登录存在安全风险”
231-
- A: 网易云风控导致,请优先考虑使用二维码登录
251+
- A: 网易云风控导致,请优先考虑使用二维码登录或直接复制Cookie
232252

233253

234254
- Q: QQ音乐无法查看个人歌单/无法播放
235-
- A: 只能重新登录,目前无解决方法,每次开游戏都得重新登录
255+
- A: 尝试重新登录
236256

237257

238258
- Q: QQ音乐服务端cookie隔一段时间就失效
239259
- A: 只能重新复制,目前无解决方法。可用 `/concerto-server reload-cookie` 重新加载cookie
240260

261+
262+
- Q: neoforge+互联环境下二维码无法加载
263+
- A: 使用 `/concerto clean-cache` 清除缓存后重试,如果还是不行,删除 `.minecraft/Concerto/cache` 文件夹
264+
241265
### 使用的开源项目
242266

243267
- [java-stream-player](https://github.com/goxr3plus/java-stream-player)

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ loader_version=0.16.10
99
fabric_version=0.119.5+1.21.5
1010

1111
# Mod Properties
12-
mod_version=1.4.0
12+
mod_version=1.4.1
1313
maven_group=top.gregtao.concerto
1414
archives_base_name=Concerto-fabric

src/main/java/top/gregtao/concerto/ConcertoClient.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import top.gregtao.concerto.command.ShareMusicCommand;
1616
import top.gregtao.concerto.config.ClientConfig;
1717
import top.gregtao.concerto.config.ConfigFile;
18+
import top.gregtao.concerto.config.PresetPlaylistsConfig;
1819
import top.gregtao.concerto.http.netease.NeteaseCloudApiClient;
1920
import top.gregtao.concerto.http.qq.QQMusicApiClient;
2021
import top.gregtao.concerto.music.list.Playlist;
@@ -73,6 +74,7 @@ public void reload(ResourceManager manager) {
7374
ClientConfig.INSTANCE.readOptions();
7475
ConcertoOptions.INSTANCE.readOptions();
7576
MusicPlayer.INSTANCE.reloadConfig(() -> LOGGER.info("Loaded general music playlist"));
77+
PresetPlaylistsConfig.LOCAL_PLAYLISTS.read();
7678
NeteaseCloudApiClient.LOCAL_USER.updateLoginStatus();
7779
QQMusicApiClient.LOCAL_USER.updateLoginStatus();
7880
});

src/main/java/top/gregtao/concerto/ConcertoServer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import org.slf4j.Logger;
1111
import org.slf4j.LoggerFactory;
1212
import top.gregtao.concerto.command.ConcertoServerCommand;
13-
import top.gregtao.concerto.config.PresetRadioConfig;
13+
import top.gregtao.concerto.config.PresetPlaylistsConfig;
1414
import top.gregtao.concerto.config.ServerConfig;
1515
import top.gregtao.concerto.http.netease.NeteaseCloudApiClient;
1616
import top.gregtao.concerto.http.qq.QQMusicApiClient;
@@ -42,7 +42,7 @@ public void reload(ResourceManager manager) {
4242

4343
public static void reload() {
4444
ServerConfig.INSTANCE.readOptions();
45-
PresetRadioConfig.INSTANCE.read();
45+
PresetPlaylistsConfig.PRESET_RADIOS.read();
4646
NeteaseCloudApiClient.INSTANCE.readCookie();
4747
QQMusicApiClient.INSTANCE.readCookie();
4848
}

src/main/java/top/gregtao/concerto/command/ConcertoServerCommand.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import net.minecraft.text.Text;
1111
import net.minecraft.util.Formatting;
1212
import top.gregtao.concerto.ConcertoServer;
13+
import top.gregtao.concerto.config.CacheManager;
1314
import top.gregtao.concerto.http.netease.NeteaseCloudApiClient;
1415
import top.gregtao.concerto.http.qq.QQMusicApiClient;
1516
import top.gregtao.concerto.network.MusicDataPacket;
@@ -83,6 +84,12 @@ public static void register(CommandDispatcher<ServerCommandSource> dispatcher, C
8384
QQMusicApiClient.INSTANCE.readCookie();
8485
return 0;
8586
})
87+
).then(
88+
CommandManager.literal("clean-cache").requires(source -> source.hasPermissionLevel(2))
89+
.executes(context -> {
90+
CacheManager.cleanAllCache();
91+
return 0;
92+
})
8693
).then(
8794
CommandManager.literal("fetch-radios")
8895
.requires(source -> source.hasPermissionLevel(0)).executes(context -> {
@@ -98,7 +105,17 @@ public static void register(CommandDispatcher<ServerCommandSource> dispatcher, C
98105
})
99106
).then(
100107
CommandManager.literal("cut").executes(context -> {
101-
ServerMusicAgent.INSTANCE.playNextMusic();
108+
ServerMusicAgent.INSTANCE.schedulePlayNext(0, false);
109+
return 0;
110+
})
111+
).then(
112+
CommandManager.literal("stop").executes(context -> {
113+
ServerMusicAgent.INSTANCE.stop();
114+
return 0;
115+
})
116+
).then(
117+
CommandManager.literal("start").executes(context -> {
118+
ServerMusicAgent.INSTANCE.start();
102119
return 0;
103120
})
104121
)

src/main/java/top/gregtao/concerto/command/MusicCommand.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@
1313
import net.minecraft.text.Text;
1414
import top.gregtao.concerto.api.CacheableMusic;
1515
import top.gregtao.concerto.api.Likeable;
16+
import top.gregtao.concerto.config.CacheManager;
1617
import top.gregtao.concerto.config.MusicCacheManager;
17-
import top.gregtao.concerto.config.PresetRadioConfig;
18+
import top.gregtao.concerto.config.PresetPlaylistsConfig;
1819
import top.gregtao.concerto.music.list.FixedPlaylist;
1920
import top.gregtao.concerto.music.meta.music.MusicMetaData;
2021
import top.gregtao.concerto.command.argument.OrderTypeArgumentType;
@@ -141,6 +142,7 @@ public static LiteralArgumentBuilder<FabricClientCommandSource> registerPlayerCo
141142
MusicPlayer.INSTANCE.reloadConfig(() ->
142143
TextUtil.commandMessageClient(context, Text.translatable("concerto.player.reload")));
143144
ClientConfig.INSTANCE.readOptions();
145+
PresetPlaylistsConfig.LOCAL_PLAYLISTS.read();
144146
MusicPlayer.resetInstance();
145147
return 0;
146148
})
@@ -228,7 +230,7 @@ public static LiteralArgumentBuilder<FabricClientCommandSource> registerPlayerCo
228230
ClientCommandManager.literal("export-as-playlist").executes(context -> {
229231
ClientPlayerEntity clientPlayer = context.getSource().getPlayer();
230232
Text playerName = clientPlayer.getDisplayName();
231-
if (PresetRadioConfig.saveToTmpFile(new FixedPlaylist(
233+
if (PresetPlaylistsConfig.saveToLocalPlaylists(new FixedPlaylist(
232234
MusicPlayerHandler.INSTANCE.getMusicList(),
233235
new PlaylistMetaData(
234236
playerName == null ? "Unknown" : playerName.getString(),
@@ -244,6 +246,11 @@ public static LiteralArgumentBuilder<FabricClientCommandSource> registerPlayerCo
244246
}
245247
return 0;
246248
})
249+
).then(
250+
ClientCommandManager.literal("clean-cache").executes(context -> {
251+
CacheManager.cleanAllCache();
252+
return 0;
253+
})
247254
);
248255
}
249256

src/main/java/top/gregtao/concerto/command/MusicRoomCommand.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ public static void register(CommandDispatcher<FabricClientCommandSource> dispatc
3232
return 0;
3333
})
3434
)).then(ClientCommandManager.literal("quit").executes(context -> {
35-
MusicRoom.clientQuit();
35+
switch (ConcertoClient.clientState) {
36+
case MUSIC_AGENT -> ClientMusicNetworkHandler.musicAgentQuit();
37+
case MUSIC_ROOM -> MusicRoom.clientQuit();
38+
}
3639
return 0;
3740
})).then(ClientCommandManager.literal("members").executes(context -> {
3841
if (MusicRoom.CLIENT_ROOM != null) {
@@ -124,7 +127,7 @@ public static boolean checkAgent(ClientPlayerEntity player) {
124127
if (ConcertoClient.clientState == ConcertoClient.ClientState.MUSIC_AGENT) {
125128
return true;
126129
} else {
127-
player.sendMessage(Text.translatable("concerto.not_available"), false);
130+
player.sendMessage(Text.translatable("concerto.agent.not_in"), false);
128131
return false;
129132
}
130133
}

src/main/java/top/gregtao/concerto/config/CacheManager.java

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package top.gregtao.concerto.config;
22

33
import top.gregtao.concerto.ConcertoClient;
4+
import top.gregtao.concerto.ConcertoServer;
45
import top.gregtao.concerto.player.MusicPlayer;
56
import top.gregtao.concerto.util.Pair;
67

@@ -10,10 +11,13 @@
1011
import java.io.InputStream;
1112
import java.nio.file.Files;
1213
import java.nio.file.LinkOption;
14+
import java.nio.file.Path;
15+
import java.nio.file.Paths;
1316
import java.nio.file.attribute.BasicFileAttributeView;
1417
import java.nio.file.attribute.BasicFileAttributes;
1518
import java.util.*;
1619
import java.util.concurrent.atomic.AtomicLong;
20+
import java.util.stream.Stream;
1721

1822
public class CacheManager {
1923

@@ -35,6 +39,35 @@ public CacheManager(String name, int maxSize) {
3539
this.maxSize = maxSize;
3640
}
3741

42+
public static void cleanAllCache() {
43+
Path cacheRoot = Paths.get(CACHE_ROOT_FOLDER);
44+
45+
if (!Files.exists(cacheRoot) || !Files.isDirectory(cacheRoot)) {
46+
ConcertoServer.LOGGER.error("Cache folder does not exist or is not a directory: {}", cacheRoot);
47+
return;
48+
}
49+
50+
try (Stream<Path> walk = Files.walk(cacheRoot, 1)) {
51+
walk.filter(path -> !path.equals(cacheRoot)).forEach(CacheManager::deleteRecursively);
52+
} catch (IOException e) {
53+
ConcertoServer.LOGGER.error("Failed to scan cache folder: {}", cacheRoot, e);
54+
}
55+
}
56+
57+
private static void deleteRecursively(Path path) {
58+
try (Stream<Path> walk = Files.walk(path)) {
59+
walk.sorted(Comparator.reverseOrder()).forEach(p -> {
60+
try {
61+
Files.delete(p);
62+
} catch (IOException e) {
63+
ConcertoServer.LOGGER.error("Failed to delete: {}", p, e);
64+
}
65+
});
66+
} catch (IOException e) {
67+
ConcertoServer.LOGGER.error("Failed to traverse path: {}", path, e);
68+
}
69+
}
70+
3871
public File getChild(String child) {
3972
return new File(this.folder.getAbsolutePath() + "/" + child);
4073
}
@@ -83,7 +116,7 @@ public boolean exists(String filename) {
83116

84117
public void addFile(String filename, InputStream inputStream) throws IOException {
85118
File file = this.getChild(filename);
86-
if (file.exists() || !file.getParentFile().mkdirs() || !file.createNewFile()) return;
119+
if (file.exists() || (!file.getParentFile().exists() && !file.getParentFile().mkdirs()) || !file.createNewFile()) return;
87120
try (FileOutputStream outputStream = new FileOutputStream(file)) {
88121
outputStream.write(inputStream.readAllBytes());
89122
}

src/main/java/top/gregtao/concerto/config/ClientConfig.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ public class ClientConfig extends ConfigFile {
1010

1111
public ClientConfigOptions options = new ClientConfigOptions();
1212

13-
public PositionXYSupplier lyricsPosSupplier, subLyricsPosSupplier, musicDetailsPosSupplier, timeProgressPosSupplier;
13+
public PositionXYSupplier
14+
lyricsPosSupplier, subLyricsPosSupplier, musicDetailsPosSupplier, timeProgressPosSupplier, coverImgPosSupplier;
1415

15-
public HexSupplier lyricsColor, subLyricsColor, musicDetailsColor, timeProgressTextColor, timeProgressColor, timeProgressBgColor;
16+
public HexSupplier
17+
lyricsColor, subLyricsColor, musicDetailsColor, timeProgressTextColor, timeProgressColor, timeProgressBgColor;
1618

1719
public ClientConfig() {
1820
super("Concerto/client_config.json");
@@ -34,6 +36,7 @@ public void parseOptions() {
3436
this.subLyricsPosSupplier = new PositionXYSupplier(this.options.subLyricsPosition);
3537
this.musicDetailsPosSupplier = new PositionXYSupplier(this.options.musicDetailsPosition);
3638
this.timeProgressPosSupplier = new PositionXYSupplier(this.options.timeProgressPosition);
39+
this.coverImgPosSupplier = new PositionXYSupplier(this.options.coverImgPosition);
3740

3841
this.lyricsColor = new HexSupplier(this.options.lyricsColor);
3942
this.subLyricsColor = new HexSupplier(this.options.subLyricsColor);
@@ -75,17 +78,23 @@ public static class ClientConfigOptions {
7578
public String subLyricsColor = "#ffffaa00";
7679

7780
public boolean displayMusicDetails = true;
78-
public String musicDetailsPosition = "1-5,0+5";
81+
public String musicDetailsPosition = "1-30,0+5";
7982
public TextAlignment musicDetailsAlignment = TextAlignment.RIGHT;
8083
public String musicDetailsColor = "#ffffffff";
8184

8285
public boolean displayTimeProgress = true;
83-
public String timeProgressPosition = "1-5,0+15";
86+
public String timeProgressPosition = "1-30,0+15";
8487
public TextAlignment timeProgressAlignment = TextAlignment.RIGHT;
8588
public String timeProgressTextColor = "#ffffffff";
8689
public String timeProgressColor = "#ff0155bc";
8790
public String timeProgressBgColor = "#ffa1c7f6";
8891

92+
public boolean displayCoverImg = true;
93+
public int coverImgSize = 25;
94+
public String coverImgPosition = "1-25,0";
95+
public boolean coverImgInCircle = true;
96+
public boolean coverImgRotate = true;
97+
8998
public boolean textShadow = true;
9099
public boolean handshakeRequired = true;
91100
}

src/main/java/top/gregtao/concerto/config/PresetRadioConfig.java renamed to src/main/java/top/gregtao/concerto/config/PresetPlaylistsConfig.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,18 @@
1818
import java.util.ArrayList;
1919
import java.util.List;
2020

21-
public class PresetRadioConfig {
21+
public class PresetPlaylistsConfig {
2222

23-
public static final PresetRadioConfig INSTANCE = new PresetRadioConfig();
23+
public static final PresetPlaylistsConfig PRESET_RADIOS = new PresetPlaylistsConfig("preset_radios");
24+
public static final PresetPlaylistsConfig LOCAL_PLAYLISTS = new PresetPlaylistsConfig("local_playlists");
2425

25-
private final File folder = new File("Concerto/preset_radios");
26+
private final File folder;
2627
private final List<Playlist> radios = new ArrayList<>();
2728

29+
public PresetPlaylistsConfig(String folder) {
30+
this.folder = new File("Concerto/" + folder);
31+
}
32+
2833
public List<Playlist> getRadios() {
2934
return this.radios;
3035
}
@@ -102,8 +107,8 @@ public static List<Playlist> fromJson(String s) {
102107
return fromJson(JsonUtil.from(s));
103108
}
104109

105-
public static boolean saveToTmpFile(Playlist playlist) {
106-
File file = new File("Concerto/concerto_playlist_export.json");
110+
public static boolean saveToLocalPlaylists(Playlist playlist) {
111+
File file = new File("Concerto/local_playlists/" + System.currentTimeMillis() + ".json");
107112
try {
108113
if (file.exists() || file.createNewFile()) {
109114
FileWriter writer = new FileWriter(file);

0 commit comments

Comments
 (0)