Merge branch 'master' of https://g.upup.cool/cstb/cstb-next
This commit is contained in:
@@ -1,178 +1,452 @@
|
||||
import { CloseSmall, Down, Edit, Plus, SettingConfig, Up } from "@icon-park/react"
|
||||
import { useState } from "react"
|
||||
import { useEffect, useState } from "react"
|
||||
import { Card, CardBody, CardHeader, CardIcon, CardTool } from "../window/Card"
|
||||
import { ToolButton } from "../window/ToolButton"
|
||||
import { addToast, NumberInput, Tab, Tabs, Tooltip } from "@heroui/react"
|
||||
import { motion } from "framer-motion"
|
||||
import { useToolStore } from "@/store/tool"
|
||||
import { useToolStore, VideoSetting as VideoConfig, VideoSettingTemplate } from "@/store/tool"
|
||||
import { useSteamStore } from "@/store/steam"
|
||||
|
||||
const VideoSetting = () => {
|
||||
const [hide, setHide] = useState(false)
|
||||
const [edit, setEdit] = useState(false)
|
||||
const tool = useToolStore()
|
||||
// const [launchOpt, setLaunchOpt] = useState(tool.state.VideoSettings[tool.state.launchIndex] || "")
|
||||
const steam = useSteamStore()
|
||||
const videoSettings = (video: VideoConfig) => {
|
||||
return [
|
||||
{
|
||||
type: "fullscreen",
|
||||
title: "全屏",
|
||||
value: video.fullscreen === "1" ? "全屏" : "窗口",
|
||||
options: ["窗口", "全屏"],
|
||||
mapping: (value: string) => {
|
||||
return (
|
||||
{
|
||||
窗口: "0",
|
||||
全屏: "1",
|
||||
}[value] || "0"
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "mat_vsync",
|
||||
title: "垂直同步",
|
||||
value: video.mat_vsync === "1" ? "开启" : "关闭",
|
||||
options: ["关闭", "开启"],
|
||||
mapping: (value: string) => {
|
||||
return (
|
||||
{
|
||||
关闭: "0",
|
||||
开启: "1",
|
||||
}[value] || "0"
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "r_low_latency",
|
||||
title: "低延迟模式",
|
||||
value: video.r_low_latency === "1" ? "开启" : "关闭",
|
||||
options: ["关闭", "开启"],
|
||||
mapping: (value: string) => {
|
||||
return (
|
||||
{
|
||||
关闭: "0",
|
||||
开启: "1",
|
||||
}[value] || "0"
|
||||
)
|
||||
},
|
||||
},
|
||||
// TODO: 改选项不在 cs2_video.txt 中
|
||||
// {
|
||||
// type: "r_player_visible_mode",
|
||||
// title: "增强角色对比度",
|
||||
// value: video.r_csgo_cmaa_enable === "1" ? "启用" : "禁用",
|
||||
// options: ["禁用", "启用"],
|
||||
// },
|
||||
{
|
||||
type: "r_csgo_cmaa_enable",
|
||||
title: "CMAA2抗锯齿",
|
||||
value: video.r_csgo_cmaa_enable === "1" ? "开启" : "关闭",
|
||||
options: ["关闭", "开启"],
|
||||
mapping: (value: string) => {
|
||||
return (
|
||||
{
|
||||
关闭: "0",
|
||||
开启: "1",
|
||||
}[value] || "0"
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "msaa_samples",
|
||||
title: "多重采样抗锯齿",
|
||||
value:
|
||||
{
|
||||
0: "无",
|
||||
2: "2X MSAA",
|
||||
4: "4X MSAA",
|
||||
8: "8X MSAA",
|
||||
}[parseInt(video.msaa_samples, 10)] || "无",
|
||||
options: ["无", "2X MSAA", "4X MSAA", "8X MSAA"],
|
||||
mapping: (value: string) => {
|
||||
return (
|
||||
{
|
||||
无: "0",
|
||||
"2X MSAA": "2",
|
||||
"4X MSAA": "4",
|
||||
"8X MSAA": "8",
|
||||
}[value] || "0"
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "videocfg_shadow_quality",
|
||||
title: "全局阴影效果",
|
||||
value: ["低", "中", "高", "非常高"][parseInt(video.videocfg_shadow_quality, 10)] || "低",
|
||||
options: ["低", "中", "高", "非常高"],
|
||||
mapping: (value: string) => {
|
||||
return (
|
||||
{
|
||||
低: "0",
|
||||
中: "1",
|
||||
高: "2",
|
||||
非常高: "3",
|
||||
}[value] || "0"
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "videocfg_dynamic_shadows",
|
||||
title: "动态阴影",
|
||||
value: ["仅限日光", "全部"][parseInt(video.videocfg_dynamic_shadows, 10)] || "仅限日光",
|
||||
options: ["仅限日光", "全部"],
|
||||
mapping: (value: string) => {
|
||||
return (
|
||||
{
|
||||
仅限日光: "0",
|
||||
全部: "1",
|
||||
}[value] || "0"
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "videocfg_texture_detail",
|
||||
title: "模型/贴图细节",
|
||||
value: ["低", "中", "高"][parseInt(video.videocfg_texture_detail, 10)] || "低",
|
||||
options: ["低", "中", "高"],
|
||||
mapping: (value: string) => {
|
||||
return (
|
||||
{
|
||||
低: "0",
|
||||
中: "1",
|
||||
高: "2",
|
||||
}[value] || "0"
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "r_texturefilteringquality",
|
||||
title: "贴图过滤模式",
|
||||
value:
|
||||
["双线性", "三线性", "异向 2X", "异向 4X", "异向 8X", "异向 16X"][
|
||||
parseInt(video.r_texturefilteringquality, 10)
|
||||
] || "双线性",
|
||||
options: ["双线性", "三线性", "异向 2X", "异向 4X", "异向 8X", "异向 16X"],
|
||||
mapping: (value: string) => {
|
||||
return (
|
||||
{
|
||||
双线性: "0",
|
||||
三线性: "1",
|
||||
"异向 2X": "2",
|
||||
"异向 4X": "3",
|
||||
"异向 8X": "4",
|
||||
"异向 16X": "5",
|
||||
}[value] || "0"
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "shaderquality",
|
||||
title: "光影细节",
|
||||
value: video.shaderquality === "1" ? "高" : "低",
|
||||
options: ["低", "高"],
|
||||
mapping: (value: string) => {
|
||||
return (
|
||||
{
|
||||
低: "0",
|
||||
高: "1",
|
||||
}[value] || "0"
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "videocfg_particle_detail",
|
||||
title: "粒子细节",
|
||||
value: ["低", "中", "高", "非常高"][parseInt(video.videocfg_particle_detail, 10)] || "低",
|
||||
options: ["低", "中", "高", "非常高"],
|
||||
mapping: (value: string) => {
|
||||
return (
|
||||
{
|
||||
低: "0",
|
||||
中: "1",
|
||||
高: "2",
|
||||
非常高: "3",
|
||||
}[value] || "低"
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "videocfg_ao_detail",
|
||||
title: "环境光遮蔽",
|
||||
value: ["已禁用", "中", "高"][parseInt(video.videocfg_ao_detail, 10)] || "已禁用",
|
||||
options: ["已禁用", "中", "高"],
|
||||
mapping: (value: string) => {
|
||||
return (
|
||||
{
|
||||
已禁用: "0",
|
||||
中: "1",
|
||||
高: "2",
|
||||
}[value] || "已禁用"
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "videocfg_hdr_detail",
|
||||
title: "高动态范围",
|
||||
value: video.videocfg_hdr_detail === "-1" ? "品质" : "性能",
|
||||
options: ["性能", "品质"],
|
||||
mapping: (value: string) => {
|
||||
return (
|
||||
{
|
||||
性能: "3",
|
||||
品质: "-1",
|
||||
}[value] || "3"
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "videocfg_fsr_detail",
|
||||
title: "Fidelity FX 超级分辨率",
|
||||
value:
|
||||
["已禁用", "超高品质", "品质", "均衡", "性能"][parseInt(video.videocfg_fsr_detail, 10)] ||
|
||||
"性能",
|
||||
options: ["性能", "均衡", "品质", "超高品质", "已禁用"],
|
||||
mapping: (value: string) => {
|
||||
return (
|
||||
{
|
||||
已禁用: "0",
|
||||
超高品质: "1",
|
||||
品质: "2",
|
||||
均衡: "3",
|
||||
性能: "4",
|
||||
}[value] || "已禁用"
|
||||
)
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
// useEffect(() => {
|
||||
// setLaunchOpt(tool.state.VideoSettings[tool.state.launchIndex] || "")
|
||||
// }, [tool.state.launchIndex, tool.state.VideoSettings])
|
||||
const [vconfig, setVconfig] = useState<VideoConfig>(tool.state.videoSetting)
|
||||
|
||||
// 设置对应关系
|
||||
// TODO Value通过实际数值映射
|
||||
const videoSettings = [
|
||||
{ type: "", title: "全屏", value: "全屏", options: ["窗口", "全屏"] },
|
||||
{ type: "", title: "垂直同步", value: "关闭", options: ["关闭", "开启"] },
|
||||
{ type: "", title: "低延迟模式", value: "关闭", options: ["关闭", "开启"] },
|
||||
{ type: "", title: "增强角色对比度", value: "禁用", options: ["禁用", "启用"] },
|
||||
{ type: "", title: "CMAA2抗锯齿", value: "关闭", options: ["关闭", "开启"] },
|
||||
{
|
||||
type: "",
|
||||
title: "多重采样抗锯齿",
|
||||
value: "2X MSAA",
|
||||
options: ["无", "2X MSAA", "4X MSAA", "8X MSAA"],
|
||||
},
|
||||
{ type: "", title: "全局阴影效果", value: "低", options: ["低", "中", "高", "非常高"] },
|
||||
{ type: "", title: "动态阴影", value: "全部", options: ["仅限日光", "全部"] },
|
||||
{ type: "", title: "模型/贴图细节", value: "中", options: ["低", "中", "高"] },
|
||||
{
|
||||
type: "",
|
||||
title: "贴图过滤模式",
|
||||
value: "异向 4X",
|
||||
options: ["双线性", "三线性", "异向 2X", "异向 4X", "异向 8X", "异向 16X"],
|
||||
},
|
||||
{ type: "", title: "光影细节", value: "低", options: ["低", "高"] },
|
||||
{ type: "", title: "粒子细节", value: "低", options: ["低", "中", "高", "非常高"] },
|
||||
{ type: "", title: "环境光遮蔽", value: "已禁用", options: ["已禁用", "中", "高"] },
|
||||
{ type: "", title: "高动态范围", value: "性能", options: ["性能", "品质"] },
|
||||
{
|
||||
type: "",
|
||||
title: "Fidelity FX 超级分辨率",
|
||||
value: "已禁用",
|
||||
options: ["性能", "均衡", "品质", "超高品质", "已禁用"],
|
||||
},
|
||||
]
|
||||
useEffect(() => {
|
||||
if (steam.state.steamDirValid && steam.currentUser())
|
||||
void tool.getVideoConfig(steam.state.steamDir, steam.currentUser()?.steam_id32 || 0)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<Tooltip content="功能测试中,尚未实装" showArrow={true} delay={300}>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardIcon>
|
||||
<SettingConfig /> 视频设置
|
||||
</CardIcon>
|
||||
<CardTool>
|
||||
{/* {tool.state.VideoSettings.map((option, index) => (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardIcon>
|
||||
<SettingConfig /> 视频设置
|
||||
</CardIcon>
|
||||
<CardTool>
|
||||
{/* {tool.state.VideoSettings.map((option, index) => (
|
||||
<ToolButton key={index} onClick={() => tool.setLaunchIndex(index)}>
|
||||
{index + 1}
|
||||
</ToolButton>
|
||||
))} */}
|
||||
{edit && (
|
||||
{edit && (
|
||||
<>
|
||||
<ToolButton onClick={() => setVconfig({ ...vconfig, ...VideoSettingTemplate.low })}>
|
||||
低
|
||||
</ToolButton>
|
||||
<ToolButton
|
||||
onClick={() => setVconfig({ ...vconfig, ...VideoSettingTemplate.middle })}
|
||||
>
|
||||
中
|
||||
</ToolButton>
|
||||
<ToolButton onClick={() => setVconfig({ ...vconfig, ...VideoSettingTemplate.high })}>
|
||||
高
|
||||
</ToolButton>
|
||||
<ToolButton
|
||||
onClick={() => setVconfig({ ...vconfig, ...VideoSettingTemplate.veryhigh })}
|
||||
>
|
||||
非常高
|
||||
</ToolButton>
|
||||
<ToolButton
|
||||
onClick={() => setVconfig({ ...vconfig, ...VideoSettingTemplate.recommend })}
|
||||
>
|
||||
推荐
|
||||
</ToolButton>
|
||||
<ToolButton
|
||||
onClick={async () => {
|
||||
await tool.setVideoConfig(
|
||||
steam.state.steamDir,
|
||||
steam.currentUser()?.steam_id32 || 0,
|
||||
vconfig
|
||||
)
|
||||
await tool.getVideoConfig(
|
||||
steam.state.steamDir,
|
||||
steam.currentUser()?.steam_id32 || 0
|
||||
)
|
||||
setEdit(false)
|
||||
addToast({ title: "应用设置成功" })
|
||||
}}
|
||||
>
|
||||
<Plus />
|
||||
应用
|
||||
</ToolButton>
|
||||
</>
|
||||
)}
|
||||
<ToolButton
|
||||
onClick={async () => {
|
||||
if (steam.state.steamDirValid && steam.currentUser())
|
||||
await tool.getVideoConfig(
|
||||
steam.state.steamDir,
|
||||
steam.currentUser()?.steam_id32 || 0
|
||||
)
|
||||
setVconfig(tool.state.videoSetting)
|
||||
setEdit(!edit)
|
||||
}}
|
||||
>
|
||||
{edit ? (
|
||||
<>
|
||||
<ToolButton>低</ToolButton>
|
||||
<ToolButton>中</ToolButton>
|
||||
<ToolButton>高</ToolButton>
|
||||
<ToolButton>非常高</ToolButton>
|
||||
<ToolButton>推荐</ToolButton>
|
||||
<ToolButton
|
||||
onClick={() => {
|
||||
addToast({ title: "测试中 功能完成后可应用设置到游戏" })
|
||||
}}
|
||||
>
|
||||
<Plus />
|
||||
应用
|
||||
</ToolButton>
|
||||
<CloseSmall />
|
||||
取消编辑
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Edit />
|
||||
编辑
|
||||
</>
|
||||
)}
|
||||
<ToolButton onClick={() => setEdit(!edit)}>
|
||||
{edit ? (
|
||||
<>
|
||||
<CloseSmall />
|
||||
取消编辑
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Edit />
|
||||
编辑
|
||||
</>
|
||||
)}
|
||||
</ToolButton>
|
||||
<ToolButton onClick={() => setHide(!hide)}>
|
||||
{hide ? (
|
||||
<>
|
||||
<Up />
|
||||
显示
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Down />
|
||||
隐藏
|
||||
</>
|
||||
)}
|
||||
</ToolButton>
|
||||
</CardTool>
|
||||
</CardHeader>
|
||||
{!hide && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
</ToolButton>
|
||||
|
||||
<ToolButton
|
||||
onClick={async () => {
|
||||
if (steam.state.steamDirValid && steam.currentUser()) {
|
||||
await tool.getVideoConfig(
|
||||
steam.state.steamDir,
|
||||
steam.currentUser()?.steam_id32 || 0
|
||||
)
|
||||
addToast({ title: "读取成功" })
|
||||
} else addToast({ title: "请先选择用户", color: "danger" })
|
||||
}}
|
||||
>
|
||||
<CardBody>
|
||||
<ul className="flex flex-wrap gap-3 mt-1">
|
||||
<li className="flex flex-col gap-1.5">
|
||||
<span className="ml-2">分辨率</span>
|
||||
<span className="flex gap-3">
|
||||
<NumberInput
|
||||
aria-label="width"
|
||||
value={tool.state.videoSetting.width}
|
||||
onValueChange={(value) => {
|
||||
tool.setVideoSetting({
|
||||
...tool.state.videoSetting,
|
||||
width: value,
|
||||
})
|
||||
}}
|
||||
radius="full"
|
||||
step={10}
|
||||
className="max-w-28"
|
||||
classNames={{ inputWrapper: "h-10" }}
|
||||
/>
|
||||
<NumberInput
|
||||
aria-label="height"
|
||||
value={tool.state.videoSetting.height}
|
||||
onValueChange={(value) => {
|
||||
tool.setVideoSetting({
|
||||
...tool.state.videoSetting,
|
||||
height: value,
|
||||
})
|
||||
}}
|
||||
radius="full"
|
||||
step={10}
|
||||
className="max-w-28"
|
||||
classNames={{ inputWrapper: "h-10" }}
|
||||
/>
|
||||
</span>
|
||||
读取
|
||||
</ToolButton>
|
||||
<ToolButton onClick={() => setHide(!hide)}>
|
||||
{hide ? (
|
||||
<>
|
||||
<Up />
|
||||
显示
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Down />
|
||||
隐藏
|
||||
</>
|
||||
)}
|
||||
</ToolButton>
|
||||
</CardTool>
|
||||
</CardHeader>
|
||||
{!hide && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
>
|
||||
<CardBody>
|
||||
<ul className="flex flex-wrap gap-3 mt-1">
|
||||
<li className="flex flex-col gap-1.5">
|
||||
<span className="ml-2">分辨率</span>
|
||||
<span className="flex gap-3">
|
||||
<NumberInput
|
||||
aria-label="width"
|
||||
value={parseInt(
|
||||
edit ? vconfig.defaultres : tool.state.videoSetting.defaultres,
|
||||
10
|
||||
)}
|
||||
onValueChange={(value) => {
|
||||
const _ = edit
|
||||
? setVconfig({
|
||||
...vconfig,
|
||||
defaultres: value.toString(),
|
||||
})
|
||||
: tool.setVideoSetting({
|
||||
...tool.state.videoSetting,
|
||||
defaultres: value.toString(),
|
||||
})
|
||||
}}
|
||||
radius="full"
|
||||
step={10}
|
||||
className="max-w-28"
|
||||
classNames={{ inputWrapper: "h-10" }}
|
||||
/>
|
||||
<NumberInput
|
||||
aria-label="height"
|
||||
value={parseInt(edit ? vconfig.defaultresheight : tool.state.videoSetting.defaultresheight, 10)}
|
||||
onValueChange={(value) => {
|
||||
const _ = edit
|
||||
? setVconfig({
|
||||
...vconfig,
|
||||
defaultresheight: value.toString(),
|
||||
})
|
||||
: tool.setVideoSetting({
|
||||
...tool.state.videoSetting,
|
||||
defaultresheight: value.toString(),
|
||||
})
|
||||
}}
|
||||
radius="full"
|
||||
step={10}
|
||||
className="max-w-28"
|
||||
classNames={{ inputWrapper: "h-10" }}
|
||||
/>
|
||||
</span>
|
||||
</li>
|
||||
{videoSettings(edit ? vconfig : tool.state.videoSetting).map((vid, index) => (
|
||||
<li className="flex flex-col gap-1.5" key={index}>
|
||||
<span className="ml-2">{vid.title}</span>
|
||||
<Tabs
|
||||
size="md"
|
||||
radius="full"
|
||||
className="min-w-36"
|
||||
fullWidth
|
||||
selectedKey={vid.value}
|
||||
onSelectionChange={(key) => {
|
||||
// console.log(vid.type, key)
|
||||
// 修改 vconfig 名为 vid.type 的 value为 key
|
||||
const _ =
|
||||
edit && key
|
||||
? setVconfig({
|
||||
...vconfig,
|
||||
[vid.type]: vid.mapping(key.toString()),
|
||||
})
|
||||
: null
|
||||
}}
|
||||
>
|
||||
{vid.options.map((opt, _) => (
|
||||
<Tab key={opt} title={opt} titleValue={opt} />
|
||||
))}
|
||||
</Tabs>
|
||||
</li>
|
||||
{videoSettings.map((vid, index) => (
|
||||
<li className="flex flex-col gap-1.5" key={index}>
|
||||
<span className="ml-2">{vid.title}</span>
|
||||
<Tabs
|
||||
selectedKey={vid.value}
|
||||
size="md"
|
||||
radius="full"
|
||||
className="min-w-36"
|
||||
fullWidth
|
||||
>
|
||||
{vid.options.map((opt, _) => (
|
||||
<Tab key={opt} title={opt} />
|
||||
))}
|
||||
</Tabs>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</CardBody>
|
||||
</motion.div>
|
||||
)}
|
||||
</Card>
|
||||
</Tooltip>
|
||||
))}
|
||||
</ul>
|
||||
</CardBody>
|
||||
</motion.div>
|
||||
)}
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user