Files
MeowOS-For-R3P2/patch_v2/ncm_app/app/logic/appstate.c
T

166 lines
5.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* logic/appstate.c — 应用全局状态:ctx/登录/歌单/歌曲/设置。仅依赖核心库 + SDK meow_config_*。 */
#include "../ncm_app_internal.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NCM_DEFAULT_DATA "/usr/data/mnt/sd_0/MeowData/os.meow.ncm/data"
int appstate_init(void)
{
const char *dd = getenv("MEOW_DATA_DIR");
if (!dd || !dd[0]) dd = NCM_DEFAULT_DATA;
strncpy(g_st.data_dir, dd, sizeof g_st.data_dir - 1);
g_st.data_dir[sizeof g_st.data_dir - 1] = 0;
ncm_ctx_init(&g_st.ctx, g_st.data_dir); /* device_id + cookie 载入 + cache */
if (g_st.ctx.cache.dir[0])
strncpy(g_st.cache_dir, g_st.ctx.cache.dir, sizeof g_st.cache_dir - 1);
else
ncm_ctx_default_cache_dir(g_st.data_dir, g_st.cache_dir, sizeof g_st.cache_dir);
appstate_load_settings();
g_st.logged_in = (g_st.ctx.cookie[0] != 0);
g_st.active_playlist = -1;
g_st.playing_song = -1;
g_st.qr_size = 0;
g_st.login_state = NCM_LOGIN_PENDING;
/* uid/nickname 从配置恢复(登录时落盘);uid 缺失时不在此阻塞校验——由 home_reload 拉歌单时
* appstate_ensure_uid 触发 login_status_check(启动快,避免首屏长时间网络阻塞)。 */
meow_config_get("ncm.uid", g_st.uid, sizeof g_st.uid);
meow_config_get("ncm.nickname", g_st.nickname, sizeof g_st.nickname);
return 0;
}
void appstate_load_settings(void)
{
g_st.cache_limit_gb = meow_config_int("ncm.cache_limit_gb", 10);
if (g_st.cache_limit_gb < 1) g_st.cache_limit_gb = 1;
if (g_st.cache_limit_gb > 100) g_st.cache_limit_gb = 100;
g_st.level = meow_config_int("ncm.level", NCM_LEVEL_HIRES);
if (g_st.level < NCM_LEVEL_STANDARD || g_st.level > NCM_LEVEL_HIRES)
g_st.level = NCM_LEVEL_HIRES;
ncm_cache_set_limit_gb(&g_st.ctx.cache, g_st.cache_limit_gb);
g_st.ctx.default_level = g_st.level;
}
void appstate_save_settings(void)
{
char b[16];
snprintf(b, sizeof b, "%d", g_st.cache_limit_gb);
meow_config_set("ncm.cache_limit_gb", b);
snprintf(b, sizeof b, "%d", g_st.level);
meow_config_set("ncm.level", b);
ncm_cache_set_limit_gb(&g_st.ctx.cache, g_st.cache_limit_gb);
g_st.ctx.default_level = g_st.level;
}
void appstate_set_logged_in(const char *uid, const char *nickname)
{
if (uid && uid[0]) { ncm_strlcpy(g_st.uid, uid, sizeof g_st.uid); meow_config_set("ncm.uid", uid); }
if (nickname && nickname[0]) {
ncm_strlcpy(g_st.nickname, nickname, sizeof g_st.nickname);
meow_config_set("ncm.nickname", nickname);
}
g_st.logged_in = 1;
}
void appstate_logout(void)
{
ncm_ctx_clear_cookie(&g_st.ctx);
g_st.logged_in = 0;
g_st.uid[0] = 0;
g_st.nickname[0] = 0;
g_st.active_playlist = -1;
g_st.playing_song = -1;
g_st.song_count = 0;
meow_config_remove("ncm.uid");
meow_config_remove("ncm.nickname");
cover_cache_reset();
}
/* 若 uid 缺失(cookie 在但没存 uid),用 login_status_check 校验并取回。返回 0=成功。 */
int appstate_ensure_uid(void)
{
if (!g_st.logged_in || !g_st.ctx.cookie[0]) return NCM_ERR_AUTH;
if (g_st.uid[0]) return NCM_OK;
char uid[32], nick[128];
int rc = ncm_login_status_check(g_st.ctx.device_id, g_st.ctx.cookie, uid, sizeof uid,
nick, sizeof nick);
if (rc == NCM_OK) {
appstate_set_logged_in(uid, nick);
return NCM_OK;
}
/* 会话失效:清 cookie → 未登录 */
if (rc == NCM_ERR_AUTH) {
ncm_ctx_clear_cookie(&g_st.ctx);
g_st.logged_in = 0;
}
return rc;
}
int appstate_load_playlists(void)
{
if (!g_st.logged_in) return NCM_ERR_AUTH;
int rc = appstate_ensure_uid();
if (rc != NCM_OK) return rc;
memset(g_st.playlists, 0, sizeof g_st.playlists);
int n = 0;
rc = ncm_api_user_playlist(g_st.ctx.device_id, g_st.ctx.cookie, g_st.uid,
NCM_PLAYLIST_MAX, 0, g_st.playlists, NCM_PLAYLIST_MAX, &n);
g_st.playlist_count = (rc == NCM_OK) ? n : 0;
return rc;
}
int appstate_load_playlist_songs(int idx)
{
if (idx < 0 || idx >= g_st.playlist_count) return NCM_ERR_ARG;
g_st.active_playlist = idx;
const ncm_playlist_t *pl = &g_st.playlists[idx];
int idn = 0;
int rc = ncm_api_playlist_detail(g_st.ctx.device_id, g_st.ctx.cookie, pl->id,
NULL, 0, NULL, 0, g_st.song_ids, NCM_SONG_MAX, &idn);
if (rc != NCM_OK) { g_st.song_count = 0; return rc; }
memset(g_st.songs, 0, sizeof g_st.songs);
int outn = 0;
for (int off = 0; off < idn; off += NCM_SONG_BATCH) {
int batch = idn - off;
if (batch > NCM_SONG_BATCH) batch = NCM_SONG_BATCH;
int bn = 0;
rc = ncm_api_song_detail(g_st.ctx.device_id, g_st.ctx.cookie, &g_st.song_ids[off],
batch, &g_st.songs[off], NCM_SONG_MAX - off, &bn);
if (rc != NCM_OK) break;
outn += bn;
if (bn < batch) break;
}
g_st.song_count = outn;
appstate_apply_playlist_cover(idx);
return NCM_OK;
}
void appstate_apply_playlist_cover(int idx)
{
if (idx < 0 || idx >= g_st.playlist_count) return;
ncm_strlcpy(g_st.cover_url, g_st.playlists[idx].cover, sizeof g_st.cover_url);
}
/* 设置播放页当前歌曲 + 封面 URL(player 页 UI 读)。idx=-1 表示清除。 */
void appstate_set_playing_song(int idx, const char *cover_url)
{
g_st.playing_song = idx;
if (cover_url && cover_url[0])
ncm_strlcpy(g_st.cover_url, cover_url, sizeof g_st.cover_url);
}
int appstate_current_playing(void)
{
if (g_st.playing_song < 0 || g_st.playing_song >= g_st.song_count) return -1;
return g_st.playing_song;
}