2 lines
17 KiB
JavaScript
2 lines
17 KiB
JavaScript
var Ce=Object.defineProperty;var Te=(s,e,n)=>e in s?Ce(s,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):s[e]=n;var j=(s,e,n)=>(Te(s,typeof e!="symbol"?e+"":e,n),n);import{D as $e,d as xe,a as Le,t as Ie,L as ce,u as Ne}from"./app-CPb3bToC.js";import{s as Oe,g as d,a as O,u as Pe,w as x}from"./chunk-DhYw-kuD.js";import{s as De}from"./chunk-BoHz2A9L.js";function ye(s){return typeof s=="string"}function Ae(s){return s instanceof ArrayBuffer}function He(){return navigator.userAgentData&&navigator.userAgentData.platform?navigator.userAgentData.platform.toLowerCase()==="windows":/windows nt|win32|win64/i.test(navigator.userAgent)}const We="5170",ke={1:"解析配置文件失败",2:"未配置模式对象",3:"切换颜色型式成功",4:"修改增益失败",5:"修改平滑失败",6:"参数配置异常",7:"未发现配置",8:"未发现音频外设",9:"未发现设备",10:"参数配置异常",11:"格式解析异常",12:"下载配置文件异常",13:"服务端已被占用"},fe={ping:"ping",pong:"pong"},J={heartbeatInterval:6e3,heartbeatTimeout:4e3,maxReconnectAttempts:1/0,reconnectDelay:1e3,debug:!1};function Fe(s={}){s.debug??(s.debug=J.debug);const e=Oe(null),n=d(We),a=O(()=>`ws://localhost:${n.value}`),i=d(null),m=d(!1),y=d(!1),f=d(0),h={interval:s.heartbeatInterval||J.heartbeatInterval,timeout:s.heartbeatTimeout||J.heartbeatTimeout},u={maxAttempts:s.maxReconnectAttempts||J.maxReconnectAttempts,delay:s.reconnectDelay||J.reconnectDelay},l=[];let c=!1,w=performance.now(),T=NaN,_=NaN,P=NaN,b=!1;function M(){if(b){console.warn("连接操作正在进行中,忽略重复请求");return}b=!0;try{e.value&&e.value.readyState!==WebSocket.CLOSED&&L(),y.value=!0,i.value=null,e.value=new WebSocket(a.value),e.value.binaryType="arraybuffer",e.value.addEventListener("open",W),e.value.addEventListener("close",z),e.value.addEventListener("message",D),e.value.addEventListener("error",S)}catch(r){F(r)}}function W(){m.value=!0,y.value=!1,i.value=null,f.value=0,c=!1,b=!1,w=performance.now(),K(),k("WebSocket 连接已建立",a.value)}function z(r){if(m.value=!1,b=!1,U(),k(`WebSocket 连接已关闭: 错误码=${r.code}, 原因=${r.reason||"未知"}`),c){i.value="律动服务连接已关闭",y.value=!1,f.value=0;return}if(f.value>=u.maxAttempts){i.value=`律动服务连接失败,已尝试${f.value}次`,y.value=!1;return}q(),f.value++}function D({data:r}){if(w=performance.now(),!!r){if(r===fe.pong){_&&(clearTimeout(_),_=NaN);return}try{l.forEach(R=>R(r))}catch(R){console.error("回调处理错误:",R)}}}function S(r){const R="律动服务连接出错";i.value=R,b=!1}function F(r){console.error("WebSocket 连接失败:",r),i.value="律动服务连接失败: "+(r.message||"未知错误"),b=!1,y.value=!1,f.value=0}function A(){c||(G(),M())}function ne(){L(),f.value=0,M()}function q(){f.value>=u.maxAttempts||(k(`将在 ${u.delay}ms 后尝试第 ${f.value+1} 次重连`),P=setTimeout(()=>A(),u.delay))}function G(){P&&(clearTimeout(P),P=NaN)}function Y(r){if(!m.value){console.warn("WebSocket 未连接,无法发送数据");return}try{e.value.send(r),w=performance.now()}catch(R){console.error("Failed to send data:",R)}}function L(){c=!0,G(),U(),e.value&&e.value.readyState!==WebSocket.CLOSED&&(e.value.removeEventListener("open",W),e.value.removeEventListener("close",z),e.value.removeEventListener("message",D),e.value.removeEventListener("error",S),e.value.readyState!==WebSocket.CLOSED&&e.value.close(),e.value=null),m.value=!1,y.value=!1,f.value=0}function K(){U(),T=setInterval(()=>{w&&performance.now()-w<h.interval||Q()},h.interval)}function U(){T&&(clearTimeout(T),T=NaN),_&&(clearTimeout(_),_=NaN)}function Q(){m.value&&(e.value.send(fe.ping),w=performance.now(),_=setTimeout(()=>{console.warn("心跳超时,连接可能已断开"),e.value&&(e.value.close(),e.value=null)},h.timeout))}function V(r){return typeof r!="function"?(console.error("Handler must be a function"),()=>{}):(l.push(r),()=>B(r))}function B(r){const R=l.indexOf(r);R!==-1&&l.splice(R,1)}function k(...r){s.debug&&console.log(...r)}function X(){L(),l.length=0}return{ws:e,port:n,error:i,connected:m,connecting:y,currentAttempt:f,connect:M,reconnect:ne,send:Y,close:L,destroy:X,onMessage:V,offMessage:B}}class qe{constructor(e,n={}){j(this,"pendingRequests",new Map);j(this,"nextId",1);j(this,"msgPrefix","id_");j(this,"_messageHandler",e=>this.messageHandler(e));this.ws=e,this.options={debug:!1,...n},this.setupMessageHandler(this.ws,this._messageHandler)}generateId(){return`${this.msgPrefix}${Date.now()}_${this.nextId++}`}parseId(e){try{const n=e.split("|")[0];return n.startsWith(this.msgPrefix)?n:null}catch{return null}}messageHandler({data:e}){const n=this.parseId(e);if(!n||!this.pendingRequests.has(n))return;const a=this.pendingRequests.get(n);try{clearTimeout(a.timeoutId),e=e.slice(n.length+1),e=this.parseResponse(e),e.status==="error"?a.reject(new Error(e.data)):a.resolve(e)}catch(i){a.reject(new Error(`Failed to handle message: ${i}`))}finally{this.pendingRequests.delete(n)}}setupMessageHandler(e,n){return e.addEventListener("message",n)}sendMessage(e){if(this.log("[send]",e),!ye(e))throw new Error(`Invalid message: ${e}`);const n=this.generateId(),a=`${n}|${e}`;return this.ws.send(a),n}sendMessageWithResponse(e,n=5e3){return new Promise((a,i)=>{const m=this.sendMessage(e);if(!m){i(new Error(`Failed to send message: ${e}`));return}const y=setTimeout(()=>{if(!this.pendingRequests.has(m))return;const f=this.pendingRequests.get(m);this.ws.readyState===WebSocket.OPEN?f.reject(new Error(`Timeout for message: ${e}`)):f.reject(new Error(`WebSocket is not connected, unable to receive response for message: ${e}`)),this.pendingRequests.delete(m)},n);this.pendingRequests.set(m,{timeoutId:y,resolve:a,reject:i})})}async sendInitMessage(e,n,a){const i=`init|USB:${e}|WIRELESS:${n}|CODE:${a}`;return await this.sendMessageWithResponse(i)}parseResponse(e){const[n,...a]=e.split("|");return n==="0"?{status:"success",data:a}:{code:n,status:"error",data:ke[n]??"Unknown error"}}parseData(e){return e==null?void 0:e.reduce((n,a)=>{const[i,m]=a.split(":");return n[i]=isNaN(Number(m))?m:Number(m),n},{})}sendStartMessage(){return this.sendMessageWithResponse("start")}sendStopMessage(){return this.sendMessageWithResponse("stop")}sendChangeMessage(e,n,a=!0){return a?this.sendMessageWithResponse(`change|${e}|${n}`):this.sendMessage(`change|${e}|${n}`)}sendSideChangeMessage(e,n,a=!0){return a?this.sendMessageWithResponse(`change_o|${e}|${n}`):this.sendMessage(`change_o|${e}|${n}`)}sendGetVersionMessage(){return this.sendMessageWithResponse("versions")}sendDriverUpdateMessage(e){return this.sendMessageWithResponse(`update|${e}`)}sendGetEffectsMessage(){return this.sendMessageWithResponse("typs")}sendGetSideEffectsMessage(){return this.sendMessageWithResponse("typs_o")}sendGetEffectParamMessage(e){return this.sendMessageWithResponse(`typConfig|${e}`)}sendGetSideEffectParamMessage(e){return this.sendMessageWithResponse(`typConfig_o|${e}`)}log(...e){this.options.debug&&console.log(...e)}dispose(){this.pendingRequests.clear(),this.ws.addEventListener("message",this._messageHandler),this.ws=null}}const Ge=["rgb","status"],Ye=new Set(["status","static"]);function Ue(s){const e=new Set(Ge),n=$e(),a=O(()=>Pe(s));function i(l){const{data:c}=l;Ae(c)?n.emit("rgb",c):ye(c)&&m(c)}function m(l){try{const[c,...w]=l.split("|");if(Ye.has(c))switch(c){case"status":case"static":n.emit("status",w[0]);break;default:n.emit(c,...w)}}catch(c){console.error("Failed to handle string message:",c)}}function y(l,c){l==null||l.addEventListener("message",c)}function f(l,c){return e.has(l)?(n.on(l,c),()=>h(l,c)):()=>{}}function h(l,c){n.off(l,c)}x(a,(l,c)=>{if(l){y(l,i);return}c==null||c.removeEventListener("message",i)},{immediate:!0});function u(){var l;n.all.clear(),(l=a.value)==null||l.removeEventListener("message",i)}return{on:f,off:h,cleanup:u}}function Z(s,e=!0){return`${e?"0x":""}${s.toString(16)}`}function Ve(s){return s?s instanceof Error?s.message:String((s==null?void 0:s.message)??s):""}function de(s){return 1+s}const me="rhythm-service-installed",pe="https://hubx.pro/static/AppDir/HEROMusicServe.exe";function Be(s){const e=d(localStorage.getItem(me)==="true"),n=d(""),a=O(()=>s==null?void 0:s.value);async function i(){if(!a.value)return;const{status:f,data:h}=await a.value.sendGetVersionMessage();if(f!=="success")return;const[u]=h;u&&(n.value=u)}function m(){localStorage.setItem(me,"true"),e.value=!0}function y(){De(pe,pe.split("/").pop()),m()}return x(a,()=>i(),{immediate:!0}),{version:n,isInstalled:e,setInstalled:m,downloadInstaller:y}}function je(s){return JSON.parse(JSON.stringify(s))}const Je={greenYellowRed:0,rainbow:1,rainbowReverse:2,spectrum:3,spectrumCycle:4,white:5,red:6,orange:7,yellow:8,green:9,blue:10,danceWithMusic:12},v={slider:"slider",select:"select",checkbox:"checkbox",color:"color",btnToggle:"btnToggle"},he=Object.entries(Je).map(([s,e])=>({label:`display_mode_${s}`,value:e})),E="mcolor",nt=s=>s===E,_e=180;function ee(s){return s.type===_e}function ze(s){return Ee.filter(e=>s.includes(e.type))}var ge;const Ee=[{id:"effect-000",type:_e,name:"close",description:"",parameters:[]},{id:"effect-001",type:169,name:"rhythm_gcdm_yg",description:"",parameters:[{prop:"gain",name:"rhythm_gain",type:v.slider,min:0,max:20,default:0},{prop:"smooth",name:"rhythm_smooth",type:v.slider,min:0,max:8,default:0},{prop:"color",name:"rhythm_palette",type:v.color,colorPresets:[E,"#23fe26","#ff4949","#ff7200","#fff005","#00d70f","#ee00f0","#ff008a","#00fefe"],default:E}]},{id:"effect-002",type:428,name:"rhythm_dtgp_cg",description:"",parameters:[{prop:"colortype",name:"rhythm_display_mode",type:v.select,options:je(he),default:(ge=he[0])==null?void 0:ge.value},{prop:"db",name:"rhythm_db",type:v.slider,min:20,max:100,default:80/2}]},{id:"effect-003",type:168,name:"rhythm_ypqw_qr",description:"",parameters:[{prop:"gain",name:"rhythm_gain",type:v.slider,min:0,max:20,default:0},{prop:"smooth",name:"rhythm_smooth",type:v.slider,min:0,max:8,default:0},{prop:"color",name:"rhythm_palette",type:v.color,colorPresets:[E,"#23fe26","#ff4949","#ff7200","#fff005","#00d70f","#ee00f0","#ff008a","#00fefe"],default:E}]},{id:"effect-004",type:170,name:"rhythm_yqxf_cg",description:"",parameters:[{prop:"gain",name:"rhythm_gain",type:v.slider,min:0,max:20,default:0},{prop:"smooth",name:"rhythm_smooth",type:v.slider,min:0,max:8,default:0},{prop:"color",name:"rhythm_palette",type:v.color,colorPresets:[E,"#23fe26","#ff4949","#ff7200","#fff005","#00d70f","#ee00f0","#ff008a","#00fefe"],default:E}]},{id:"effect-005",type:171,name:"rhythm_gcbh_rs",description:"",parameters:[]},{id:"effect-006",type:172,name:"rhythm_xstt_cg",description:"",parameters:[{prop:"gain",name:"rhythm_gain",type:v.slider,min:0,max:20,default:0},{prop:"smooth",name:"rhythm_smooth",type:v.slider,min:0,max:8,default:0},{prop:"color",name:"rhythm_palette",type:v.color,colorPresets:[E,"#23fe26","#ff4949","#ff7200","#fff005","#00d70f","#ee00f0","#ff008a","#00fefe"],default:E}]},{id:"effect-007",type:173,name:"rhythm_bhzy_jq",description:"",parameters:[{prop:"gain",name:"rhythm_gain",type:v.slider,min:0,max:20,default:0},{prop:"smooth",name:"rhythm_smooth",type:v.slider,min:0,max:8,default:0},{prop:"color",name:"rhythm_palette",type:v.color,colorPresets:[E,"#23fe26","#ff4949","#ff7200","#fff005","#00d70f","#ee00f0","#ff008a","#00fefe"],default:E}]}],te=500,ve=[{name:"close",value:te},{name:"rhythm_yqxf_cg",value:501,description:"",parameters:[{prop:"color",name:"rhythm_palette",type:v.color,colorPresets:[E,"#23fe26","#ff4949","#ff7200","#fff005","#00d70f","#ee00f0","#ff008a","#00fefe"],default:E}]},{name:"rhythm_gcdm_yg",value:502,description:"",parameters:[{prop:"color",name:"rhythm_palette",type:v.color,colorPresets:[E,"#23fe26","#ff4949","#ff7200","#fff005","#00d70f","#ee00f0","#ff008a","#00fefe"],default:E}]},{name:"rhythm_gcbh_rs",value:503,description:"",parameters:[]}],Ke=new Set([18691697672213]),N={Main:"main",Side:"side"};function Qe(s){return s&&s.uuid!==0}const st=xe("model_kb_by_v3_rhythm",()=>{if(!He())return{isSupport:d(!1),isSideEffectSupport:d(!1),isRunning:d(!1),isSideEffectRunning:d(!1)};const s=Le(),e=d(N.Main),n=d(!1),a=d(!1),i=d(!1),m=O(()=>!Ke.has(s.current_device.uuid)&&a.value&&i.value),y=d(!1),f=d(!1),h=Fe(),u=d(null),l=Ue(h.ws),c=l.on("status",async()=>await q()),w=Be(u),T=d(!1),_=d(!1),P=O(()=>!T.value&&_.value&&!h.connecting.value&&h.connected.value),b=d(),M=O(()=>Ee.find(ee)),W=d([M.value]),z=O(()=>e.value===N.Main?W.value:D.value),D=d(ve),S=d(M.value),F=O(()=>D.value.find(t=>t.value===te)),A=d(null);function ne(t){async function o(){var p;T.value=!0,_.value=!1,(p=u.value)==null||p.dispose(),u.value=new qe(t,{debug:!1}),await k().finally(()=>{T.value=!1})}return t.addEventListener("open",o),()=>{t.removeEventListener("open",o)}}async function q(){const[t,o]=await Promise.all([G(),Y()]);S.value=e.value===N.Side?o:t,A.value=await V(S.value,e.value)}async function G(){if(!u.value)return;const t=await u.value.sendGetEffectsMessage();if((t==null?void 0:t.status)!=="success")return;const o=u.value.parseData(t.data);if(!o)return;const{Typs:p,Current:g}=o,$=ze(p);W.value=$.length?$:[M.value];const C=W.value.find(H=>H.type===Number(g))??M.value;return r(!ee(C)),C}async function Y(){if(!u.value||!m.value)return;const t=await u.value.sendGetSideEffectsMessage();if((t==null?void 0:t.status)!=="success")return;const o=u.value.parseData(t.data);if(!o)return;const{Typs:p,Current:g}=o,$=ve.filter(H=>p.includes(H.value));D.value=$.length?$:[F.value];const C=D.value.find(H=>H.value===Number(g))??F.value;return f.value=!K(C),C}async function L(t,o,p=!0,g=e.value){return g===N.Side?await u.value.sendSideChangeMessage(t,o,p):await u.value.sendChangeMessage(t,o,p)}function K(t){return t.value===te}async function U(t,o=!0){const p=o?ce():{close:()=>{}};try{await L("mode",t.value,!0,N.Side),B(t),f.value=!K(t)}catch{throw new Error("灯箱律动切换失败")}finally{p.close()}}async function Q(t,o=!1,p=!0){var $;if(!t||!o&&(($=S.value)==null?void 0:$.id)===t.id||!u.value)return;const g=p?ce():{close:()=>{}};try{await L("mode",t.type,!0,N.Main),B(t);const C=ee(t);r(!C)}catch(C){throw console.error("律动模式切换失败",C),new Error("切换失败")}finally{g.close()}}async function V(t,o){if(!t)return{};if(ee(t)||t.value===te)return{};let p=null;if(o===N.Side?p=await u.value.sendGetSideEffectParamMessage(t.value):p=await u.value.sendGetEffectParamMessage(t.type),(p==null?void 0:p.status)!=="success")return{};const g=u.value.parseData(p.data);return g||{}}async function B(t){if(!t){S.value=M.value,A.value=null;return}S.value=t,A.value=await V(t,e.value)}async function k(){if(_.value||!h.connected.value||!u.value||!s.current_device)return;const{product_id:t,vendor_id:o,report_id_io_rx:p,send_payload_length:g,uuid:$,type_connection:C,type_channel:H}=s.current_device,ae=C==="wired",re=H==="feature_report",Re=re?de(g):0,be=re?0:de(g),oe=`${Z(o)},${Z(t)},${Z(p)},${Re},${be}`,ie="NULL";try{await u.value.sendInitMessage(ae?oe:ie,ae?ie:oe,Z($,!1)),_.value=!0}catch(ue){console.error(ue),_.value=!1,r(!1),f.value=!1;const le=Ve(ue);b.value={type:"init",message:`初始化失败${le?`: ${le}`:""}`}}}async function X(){const t=await Ne().controller;if(!t){n.value=!1,a.value=!1;return}const o=await t.check_rhythm_support();if(o){n.value=o.main,a.value=o.lightBox;return}}function r(t){y.value=t}async function R(t,o){if(!Qe(t)){n.value=!1,a.value=!1;return}t.product_name!==(o==null?void 0:o.product_name)&&await X()}function Se(t){t?h.connect():(r(!1),f.value=!1,h.close())}function we(t){if(t){const[o,p,g]=t.split(".").map(Number);if(!Number.isNaN(g)){i.value=g>=2,i.value&&Y();return}}i.value=!1}function se(){var t;T.value=!1,_.value=!1,b.value=null,I==null||I(),I=null,c(),(t=u.value)==null||t.dispose(),l.cleanup(),h.destroy(),S.value=M.value}function Me(){n.value=!1,a.value=!1,i.value=!1,r(!1),f.value=!1,se()}x(P,async t=>{if(!t){r(!1),f.value=!1;return}try{await q()}catch{Q(M.value,!1,!0)}},{immediate:!0}),x(h.error,t=>{t&&(r(!1),f.value=!1,b.value={type:"connect",message:`${Ie("music_rhythm_service_connection_failed")} ${h.currentAttempt.value?"("+h.currentAttempt.value+")":""}`})});let I=null;return x(h.ws,t=>{t&&(I==null||I(),I=ne(t))},{immediate:!0}),x(()=>s.current_device,R,{immediate:!0}),x(n,Se),x(()=>w.version.value,we,{immediate:!0}),x(e,async t=>{t===N.Main?S.value=await G():S.value=await Y(),A.value=await V(S.value,e.value)}),{reset:Me,isSupport:n,isSideEffectSupport:m,checkSupport:X,isRunning:y,isSideEffectRunning:f,changeRunningStatus:r,position:e,effects:z,activeEffect:S,closeEffect:M,closeSideEffect:F,effectParameterForm:A,getEffects:q,changeCurrentRhythm:Q,changeCurrentSideRhythm:U,handlePhythmExeInit:k,installer:w,initializing:T,inited:_,isReady:P,error:b,wsClient:h,messageSender:u,messageReceiver:l,sendChangeMessage:L,cleanup:se}});export{We as D,v as F,N as R,ve as S,ee as a,je as c,nt as i,Ke as l,st as u};
|