Browse Source

增加热更新,优化相关问题,增加罗技control

caner 2 years ago
parent
commit
68fdd448af
13 changed files with 168 additions and 127 deletions
  1. 3 2
      .eslintrc.json
  2. 1 1
      README.md
  3. 2 1
      index.html
  4. 31 21
      main.js
  5. 6 5
      package.json
  6. 22 0
      preload.js
  7. 0 2
      public/loader.js
  8. 3 9
      src/App.vue
  9. 0 1
      src/components/icon.vue
  10. 15 6
      src/components/loading.vue
  11. 2 2
      src/components/login.vue
  12. 82 76
      src/views/index/index.vue
  13. 1 1
      vite.config.ts

+ 3 - 2
.eslintrc.json

@@ -35,7 +35,8 @@
     "vue/v-on-event-hyphenation": 0,
     "vue/v-on-event-hyphenation": 0,
     "no-promise-executor-return": 0,
     "no-promise-executor-return": 0,
     "no-shadow": 0,
     "no-shadow": 0,
-    "prefer-destructuring": 1,
-    "no-new": 0
+    "prefer-destructuring": 0,
+    "no-new": 0,
+    "func-names": 0
   }
   }
 }
 }

+ 1 - 1
README.md

@@ -1,6 +1,6 @@
 # 控制端
 # 控制端
 ```
 ```
- 本版本为vue3+ts+eslint+electron
+ 本版本适配罗技G923 方向盘+油门
 ```
 ```
 ## 注意
 ## 注意
 ```
 ```

+ 2 - 1
index.html

@@ -14,6 +14,8 @@
       user-select: none;
       user-select: none;
       width: 100%;
       width: 100%;
       height: 100%;
       height: 100%;
+      min-width: 1300px;
+      min-height: 760px;
       overflow: hidden;
       overflow: hidden;
     }
     }
   </style>
   </style>
@@ -22,7 +24,6 @@
 <body>
 <body>
   <div id="app"></div>
   <div id="app"></div>
   <script type="module" src="./src/main.ts"></script>
   <script type="module" src="./src/main.ts"></script>
-  <script src="./loader.js"></script>
 </body>
 </body>
 
 
 </html>
 </html>

+ 31 - 21
main.js

@@ -1,24 +1,21 @@
-const {
-  app, BrowserWindow, Menu, ipcMain
-} = require('electron')// 引入electron
-let win; let
-  loadingWin
+const {app, BrowserWindow, Menu, ipcMain, globalShortcut } = require('electron')// 引入electron
+const path = require('path')
+let win, loadingWin;
 Menu.setApplicationMenu(null) // 去掉菜单栏
 Menu.setApplicationMenu(null) // 去掉菜单栏
 app.commandLine.appendSwitch('wm-window-animations-disabled') // 拖动闪屏
 app.commandLine.appendSwitch('wm-window-animations-disabled') // 拖动闪屏
 
 
 // 消息通知
 // 消息通知
-function notifiction (title, options) {
-	const WebNotification =  window.Notification || window.mozNotification || window.webkitNotification
-    const isTrue = WebNotification.requestPermission(result => {
-      return (result === 'granted') // granted(允许) || denied(拒绝)
-    })
-    const noti =  new WebNotification(title, options)
-    noti.onclick=()=>{
-      console.log('关闭')
-    }
+function notifiction(title, options) {
+  const WebNotification = window.Notification || window.mozNotification || window.webkitNotification
+  const isTrue = WebNotification.requestPermission(result => {
+    return (result === 'granted') // granted(允许) || denied(拒绝)
+  })
+  const noti = new WebNotification(title, options)
+  noti.onclick = () => {
+    console.log('关闭')
+  }
 }
 }
 
 
-
 // 创建loading 窗口
 // 创建loading 窗口
 const showLoading = () => {
 const showLoading = () => {
   loadingWin = new BrowserWindow({
   loadingWin = new BrowserWindow({
@@ -35,22 +32,30 @@ const showLoading = () => {
     loadingWin = null
     loadingWin = null
   })
   })
 }
 }
+
 // 创建主程序 窗口
 // 创建主程序 窗口
 const createWindow = () => {
 const createWindow = () => {
   win = new BrowserWindow({
   win = new BrowserWindow({
     minWidth: 1300,
     minWidth: 1300,
     minHeight: 760,
     minHeight: 760,
+    width: 1300,
+    height: 760,
     webPreferences: {
     webPreferences: {
-      contextIsolation: false,
+      contextIsolation: true,
       nodeIntegration: true,
       nodeIntegration: true,
-      webSecurity: false // 去掉跨越
+      webSecurity: false, // 去掉跨越
+      preload: path.join(__dirname, 'preload.js')
     },
     },
     show: false
     show: false
   })// 创建一个窗口
   })// 创建一个窗口
-  // 在窗口内要展示的内容index.html 就是打包生成的index.html
-  win.loadFile('dist/index.html')
-  // 开启调试工具
-  // win.webContents.openDevTools();
+
+  // 不同环境加载不同文件
+  if (app.isPackaged) {
+    win.loadFile('dist/index.html')
+  } else {
+    win.loadURL('http://localhost:6547/')
+  }
+  
   // 事件监听
   // 事件监听
   win.on('close', () => {
   win.on('close', () => {
     // 回收BrowserWindow对象
     // 回收BrowserWindow对象
@@ -67,6 +72,11 @@ app.on('ready', async () => {
     loadingWin.close()
     loadingWin.close()
     win.show()
     win.show()
   })
   })
+  // 在BrowserWindow创建完成后,注册全局快捷键
+  globalShortcut.register('Control+F12', () => {
+    win.webContents.toggleDevTools()
+  })
+  
 })
 })
 
 
 app.on('window-all-closed', () => {
 app.on('window-all-closed', () => {

+ 6 - 5
package.json

@@ -5,14 +5,15 @@
   "author": "Caner",
   "author": "Caner",
   "description": "控制端",
   "description": "控制端",
   "scripts": {
   "scripts": {
-    "dev": "vite",
-    "edev": "yarn build && electron .",
-    "build": "vue-tsc --noEmit && vite build",
+    "dev": "vite & yarn edev",
+    "build": "vue-tsc --noEmit && vite build && yarn pmake",
+    "edev": "electron .",
     "make": "electron-forge make",
     "make": "electron-forge make",
     "pmake": "electron-forge package"
     "pmake": "electron-forge package"
   },
   },
   "dependencies": {
   "dependencies": {
     "echarts": "^5.4.2",
     "echarts": "^5.4.2",
+    "node-hid": "^2.1.2",
     "socket.io-client": "^4.6.1",
     "socket.io-client": "^4.6.1",
     "vue": "^3.3.2",
     "vue": "^3.3.2",
     "vue-router": "^4.2.0"
     "vue-router": "^4.2.0"
@@ -23,6 +24,7 @@
     "@types/node": "^18.15.3",
     "@types/node": "^18.15.3",
     "@typescript-eslint/parser": "^5.40.0",
     "@typescript-eslint/parser": "^5.40.0",
     "@vitejs/plugin-vue": "^4.2.3",
     "@vitejs/plugin-vue": "^4.2.3",
+    "electron": "^23.1.2",
     "eslint": "^8.40.0",
     "eslint": "^8.40.0",
     "eslint-config-airbnb-base": "^15.0.0",
     "eslint-config-airbnb-base": "^15.0.0",
     "eslint-plugin-import": "^2.27.5",
     "eslint-plugin-import": "^2.27.5",
@@ -32,9 +34,8 @@
     "vite": "^4.3.6",
     "vite": "^4.3.6",
     "vite-plugin-compression": "^0.5.1",
     "vite-plugin-compression": "^0.5.1",
     "vite-plugin-eslint": "^1.8.1",
     "vite-plugin-eslint": "^1.8.1",
-    "vue-tsc": "^1.6.5",
     "vite-plugin-svg-icons": "^2.0.1",
     "vite-plugin-svg-icons": "^2.0.1",
-    "electron": "^23.1.2"
+    "vue-tsc": "^1.6.5"
   },
   },
   "config": {
   "config": {
     "forge": {
     "forge": {

+ 22 - 0
preload.js

@@ -0,0 +1,22 @@
+const { contextBridge, ipcRenderer } = require('electron')
+const HID = require('node-hid');
+const devices = HID.devices()
+const logitech = devices.filter(el => el.manufacturer == 'Logitech')
+const data = new HID.HID(logitech[0].vendorId, logitech[0].productId)
+// data.on('data', db => {
+//   // 拨片 2 是右拨片,1是左拨片,0是取消
+//   const bp = db[6] === 2 ? '右拨片' : db[6] === 1 ? "左拨片" : ''
+//   const fx = parseInt(db[44], 10)  // 转10进制
+//   const fxp = fx < 123 ? '左轮' + fx : fx > 132 ? '右轮' + fx : ''
+//   const ym = parseInt(db[46], 10) //油门
+//   console.log(66, bp, fxp, 255 - ym);
+
+// })
+
+
+contextBridge.exposeInMainWorld('$electron', {
+  send: (channel, args) => ipcRenderer.send(channel, args),
+  once: (channel, listener) => ipcRenderer.once(channel, listener),
+  on: (channel, listener) => ipcRenderer.on(channel, listener),
+  onContrl: (callBack) => data.on('data', db => callBack(db))
+})

+ 0 - 2
public/loader.js

@@ -1,2 +0,0 @@
-const electron = require('electron');//引入electron
-window['$electron'] = electron

+ 3 - 9
src/App.vue

@@ -1,20 +1,14 @@
 <template>
 <template>
-  <loading v-if="showLoading" />
-  <router-view
-    v-else
-    v-resize
-  />
+  <router-view />
 </template>
 </template>
 <script setup lang='ts'>
 <script setup lang='ts'>
-import { ref, onMounted } from 'vue'
-import loading from '@/components/loading.vue'
+import { onMounted } from 'vue'
 
 
-const showLoading = ref(false)
 onMounted(() => {
 onMounted(() => {
   // 通知主进程是否完成渲染
   // 通知主进程是否完成渲染
   const electron = window.$electron || null
   const electron = window.$electron || null
   if (electron) {
   if (electron) {
-    electron.ipcRenderer.send('close-loading')
+    electron.send('close-loading')
   }
   }
 })
 })
 </script>
 </script>

+ 0 - 1
src/components/icon.vue

@@ -16,7 +16,6 @@ const newSize = computed(() => `${props.size ? (`${props.size / 100}rem`) : '0.1
     :fill="newColor"
     :fill="newColor"
     :style="`width:${newSize};height:${newSize}`"
     :style="`width:${newSize};height:${newSize}`"
   >
   >
-
     <use
     <use
       :href="symbolId"
       :href="symbolId"
       :fill="newColor"
       :fill="newColor"

+ 15 - 6
src/components/loading.vue

@@ -13,12 +13,21 @@
 }
 }
 
 
 @-webkit-keyframes spin {
 @-webkit-keyframes spin {
-  0% { -webkit-transform: rotate(0deg); }
-  100% { -webkit-transform: rotate(360deg); }
+  0% {
+    -webkit-transform: rotate(0deg);
+  }
+
+  100% {
+    -webkit-transform: rotate(360deg);
+  }
 }
 }
 
 
 @keyframes spin {
 @keyframes spin {
-  0% { transform: rotate(0deg); }
-  100% { transform: rotate(360deg); }
-}
-</style>
+  0% {
+    transform: rotate(0deg);
+  }
+
+  100% {
+    transform: rotate(360deg);
+  }
+}</style>

+ 2 - 2
src/components/login.vue

@@ -3,8 +3,8 @@ import { ref } from 'vue'
 
 
 const name = ref('')
 const name = ref('')
 const roomID = ref('')
 const roomID = ref('')
-defineProps<{ err: string}>()
-const emit = defineEmits<{(evt: 'loginBack', value: { name: string, roomID: string }): void}>()
+defineProps<{ err: string }>()
+const emit = defineEmits<{(evt: 'loginBack', value: { name: string, roomID: string }): void }>()
 function login() {
 function login() {
   if (name.value && roomID.value) emit('loginBack', { name: name.value, roomID: roomID.value })
   if (name.value && roomID.value) emit('loginBack', { name: name.value, roomID: roomID.value })
 }
 }

+ 82 - 76
src/views/index/index.vue

@@ -7,6 +7,7 @@ import Login from '@/components/login.vue'
 import Gauge from '@/components/gauge.vue'
 import Gauge from '@/components/gauge.vue'
 import Record from '@/components/record.vue'
 import Record from '@/components/record.vue'
 import Battery from '@/components/battery.vue'
 import Battery from '@/components/battery.vue'
+import Loading from '@/components/loading.vue'
 
 
 const sleep = (ms: number) => new Promise((res) => setTimeout(res, ms))
 const sleep = (ms: number) => new Promise((res) => setTimeout(res, ms))
 const socket = ref(null as null | Socket)
 const socket = ref(null as null | Socket)
@@ -44,32 +45,32 @@ function sendAudio(blob: Blob) {
   })
   })
 }
 }
 
 
-// 挡位
-function Gear(speed: number, num: number) {
-  // 低速档
-  if (speed === 1) {
-    if (num < 116) {
-      // 前
-      num = 120
-    } else if (num >= 120 && num <= 131) {
-      num = 128
-    } else if (num > 140) {
-      // 后
-      num = 140
-    }
-  }
-  // 高速档
-  if (speed === 2) {
-    if (num < 96) {
-      num = 96
-    } else if (num >= 120 && num <= 131) {
-      num = 128
-    } else if (num > 160) {
-      num = 160
-    }
-  }
-  return num
-}
+// // 挡位
+// function Gear(speed: number, num: number) {
+//   // 低速档
+//   if (speed === 1) {
+//     if (num < 116) {
+//       // 前
+//       num = 120
+//     } else if (num >= 120 && num <= 131) {
+//       num = 128
+//     } else if (num > 140) {
+//       // 后
+//       num = 140
+//     }
+//   }
+//   // 高速档
+//   if (speed === 2) {
+//     if (num < 96) {
+//       num = 96
+//     } else if (num >= 120 && num <= 131) {
+//       num = 128
+//     } else if (num > 160) {
+//       num = 160
+//     }
+//   }
+//   return num
+// }
 
 
 // 登录
 // 登录
 function login(data: { name: string, roomID: string }) {
 function login(data: { name: string, roomID: string }) {
@@ -84,43 +85,43 @@ function login(data: { name: string, roomID: string }) {
   }
   }
 }
 }
 
 
-// 手柄数据
-function ControlData() {
-  const data = navigator.getGamepads()
-  const db = data[0]
-  if (!db) return
-  // 挡位选择AB
-  if (db.buttons[1].touched) speed.value = 2
-  if (db.buttons[0].touched) speed.value = 1
-  // 语音按键R2
-  audioState.value = db.buttons[7].touched
-  // 静音X3
-  mutedState.value = db.buttons[3].touched
-  // 播放警笛Y2
-  warnAudio.value = db.buttons[2].touched
-  // console.log(db.buttons);
-  const params = {
-    v0: Math.floor(db.axes[0] * 128 + 128),
-    v1: Math.floor(db.axes[1] * 128 + 128),
-    v2: Math.floor(db.axes[2] * 128 + 128),
-    v3: Gear(speed.value, Math.floor(db.axes[3] * 128 + 128))
-  }
+// // 手柄数据
+// function ControlData() {
+//   const data = navigator.getGamepads()
+//   const db = data[0]
+//   if (!db) return
+//   // 挡位选择AB
+//   if (db.buttons[1].touched) speed.value = 2
+//   if (db.buttons[0].touched) speed.value = 1
+//   // 语音按键R2
+//   audioState.value = db.buttons[7].touched
+//   // 静音X3
+//   mutedState.value = db.buttons[3].touched
+//   // 播放警笛Y2
+//   warnAudio.value = db.buttons[2].touched
+//   // console.log(db.buttons);
+//   const params = {
+//     v0: Math.floor(db.axes[0] * 128 + 128),
+//     v1: Math.floor(db.axes[1] * 128 + 128),
+//     v2: Math.floor(db.axes[2] * 128 + 128),
+//     v3: Gear(speed.value, Math.floor(db.axes[3] * 128 + 128))
+//   }
 
 
-  if (socket.value && socket.value.connected) socket.value.emit('msg', { type: 'conctrl', conctrl: params })
-  requestAnimationFrame(ControlData)
-}
+//   if (socket.value && socket.value.connected) socket.value.emit('msg', { type: 'conctrl', conctrl: params })
+//   requestAnimationFrame(ControlData)
+// }
 
 
-// 手柄连接
-function conControl() {
-  contrlState.value = true
-  ControlData()
-}
+// // 手柄连接
+// function conControl() {
+//   contrlState.value = true
+//   ControlData()
+// }
 
 
-// 手柄断开连接
-function disControl() {
-  contrlState.value = false
-  cancelAnimationFrame(ControlData as any)
-}
+// // 手柄断开连接
+// function disControl() {
+//   contrlState.value = false
+//   cancelAnimationFrame(ControlData as any)
+// }
 
 
 // 关闭
 // 关闭
 function close(err?: string) {
 function close(err?: string) {
@@ -133,10 +134,11 @@ function close(err?: string) {
   socket.value = null
   socket.value = null
   Peer.value = null
   Peer.value = null
   num.value = 0
   num.value = 0
-  cancelAnimationFrame(ControlData as any)
-  window.removeEventListener('gamepadconnected', conControl)
-  window.removeEventListener('gamepaddisconnected', disControl)
+  // cancelAnimationFrame(ControlData as any)
+  // window.removeEventListener('gamepadconnected', conControl)
+  // window.removeEventListener('gamepaddisconnected', disControl)
 }
 }
+
 /**
 /**
  * 网络连接
  * 网络连接
  * @param host
  * @param host
@@ -188,8 +190,11 @@ function intSoketRtc(host: string) {
         // ICE连接成功|初始化摇杆
         // ICE连接成功|初始化摇杆
         if (state === 'connected') {
         if (state === 'connected') {
           // init Control
           // init Control
-          window.addEventListener('gamepadconnected', conControl)
-          window.addEventListener('gamepaddisconnected', disControl)
+          // window.addEventListener('gamepadconnected', conControl)
+          // window.addEventListener('gamepaddisconnected', disControl)
+          window.$electron.onContrl((db:ArrayBuffer) => {
+            console.log('123', db)
+          })
           await sleep(3000)
           await sleep(3000)
           showLoading.value = false
           showLoading.value = false
         }
         }
@@ -220,17 +225,18 @@ function intSoketRtc(host: string) {
   socket.value.on('connect_error', () => close('服务器连接失败'))
   socket.value.on('connect_error', () => close('服务器连接失败'))
 }
 }
 
 
-watch(() => mutedState.value, (v) => {
-  if (v) {
-    const state = !!(num.value % 2)
-    muted.value = state
-    if (socket.value && socket.value.connected) socket.value.emit('msg', { type: 'contrlAudio', contrlAudio: state })
-    num.value++
-  }
-})
-watch(() => warnAudio.value, (v) => {
-  if (v && socket.value && socket.value.connected) socket.value.emit('msg', { type: 'warnAudio', warnAudio: v })
-})
+// watch(() => mutedState.value, (v) => {
+//   if (v) {
+//     const state = !!(num.value % 2)
+//     muted.value = state
+//     if (socket.value && socket.value.connected) socket.value.emit('msg', { type: 'contrlAudio', contrlAudio: state })
+//     num.value++
+//   }
+// })
+// watch(() => warnAudio.value, (v) => {
+//   if (v && socket.value && socket.value.connected) socket.value.emit('msg', { type: 'warnAudio', warnAudio: v })
+// })
+
 onMounted(() => {
 onMounted(() => {
   intSoketRtc(HOST.value)
   intSoketRtc(HOST.value)
 })
 })

+ 1 - 1
vite.config.ts

@@ -25,7 +25,7 @@ export default () => defineConfig({
   server: {
   server: {
     host: '0.0.0.0',
     host: '0.0.0.0',
     port: 6547,
     port: 6547,
-    open: true,
+    open: false,
     strictPort: false,
     strictPort: false,
     https: false,
     https: false,
   },
   },