更新
| @@ -1,4 +1,6 @@ | ||||
| namespace cmonitor.libs | ||||
| using System; | ||||
|  | ||||
| namespace cmonitor.libs | ||||
| { | ||||
|     internal interface IShareMemory | ||||
|     { | ||||
| @@ -14,5 +16,6 @@ | ||||
|  | ||||
|         public void ReadArray(int position, byte[] bytes, int offset, int length); | ||||
|         public void WriteArray(int position, byte[] data, int offset, int length); | ||||
|         public void WritSpan(int position, Span<byte> span); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -404,6 +404,38 @@ namespace cmonitor.libs | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         public bool Update(int index, Span<byte> span, ShareMemoryAttribute addAttri = ShareMemoryAttribute.None, | ||||
|             ShareMemoryAttribute removeAttri = ShareMemoryAttribute.None) | ||||
|         { | ||||
|             if (accessorLocal == null && accessorGlobal == null) return false; | ||||
|             if (span.Length > shareMemoryHeadSize + itemSize) return false; | ||||
|  | ||||
|             lock (lockObj) | ||||
|             { | ||||
|                 int valIndex = index * itemSize + 8 + shareMemoryHeadSize; | ||||
|                 if (accessorLocal != null) | ||||
|                 { | ||||
|                     accessorLocal.WriteInt(valIndex, span.Length); | ||||
|                     accessorLocal.WritSpan(valIndex+4, span); | ||||
|                 } | ||||
|                 if (accessorGlobal != null) | ||||
|                 { | ||||
|                     accessorGlobal.WriteInt(valIndex, span.Length); | ||||
|                     accessorGlobal.WritSpan(valIndex, span); | ||||
|                 } | ||||
|                 IncrementVersion(index); | ||||
|                 if (removeAttri > 0) | ||||
|                 { | ||||
|                     RemoveAttribute(index, removeAttri); | ||||
|                 } | ||||
|                 if (addAttri > 0) | ||||
|                 { | ||||
|                     AddAttribute(index, addAttri); | ||||
|                 } | ||||
|             } | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         private ShareMemoryAttribute ReadAttribute(IShareMemory accessor, int index) | ||||
|         { | ||||
|             if (accessor == null || index >= length) return ShareMemoryAttribute.None; | ||||
|   | ||||
| @@ -60,6 +60,13 @@ namespace cmonitor.libs | ||||
|                 Marshal.Copy(bytes, offset, shmPtr + position, length); | ||||
|             } | ||||
|         } | ||||
|         public unsafe void WritSpan(int position, Span<byte> span) | ||||
|         { | ||||
|             if (shmPtr != IntPtr.Zero) | ||||
|             { | ||||
|                 span.CopyTo(new Span<byte>((void*)(shmPtr + position), span.Length)); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public byte ReadByte(int position) | ||||
|         { | ||||
| @@ -131,5 +138,7 @@ namespace cmonitor.libs | ||||
|  | ||||
|         [DllImport(LIBC_LIBRARY, EntryPoint = "shm_unlink", SetLastError = true)] | ||||
|         public static extern int ShmUnlink(string name); | ||||
|  | ||||
|  | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -60,6 +60,13 @@ namespace cmonitor.libs | ||||
|                 Marshal.Copy(bytes, offset, shmPtr + position, length); | ||||
|             } | ||||
|         } | ||||
|         public unsafe void WritSpan(int position, Span<byte> span) | ||||
|         { | ||||
|             if (shmPtr != IntPtr.Zero) | ||||
|             { | ||||
|                 span.CopyTo(new Span<byte>((void*)(shmPtr + position), span.Length)); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public byte ReadByte(int position) | ||||
|         { | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
| using System.IO; | ||||
| using System.IO.MemoryMappedFiles; | ||||
| using System.Runtime.InteropServices; | ||||
| using static System.Runtime.InteropServices.JavaScript.JSType; | ||||
|  | ||||
| namespace cmonitor.libs | ||||
| { | ||||
| @@ -57,6 +58,13 @@ namespace cmonitor.libs | ||||
|                 accessorLocal.WriteArray(position, data, offset, length); | ||||
|             } | ||||
|         } | ||||
|         public void WritSpan(int position, Span<byte> span) | ||||
|         { | ||||
|             if (accessorLocal != null) | ||||
|             { | ||||
|                 accessorLocal.SafeMemoryMappedViewHandle.WriteSpan<byte>((ulong)position, span); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public byte ReadByte(int position) | ||||
|         { | ||||
| @@ -106,6 +114,8 @@ namespace cmonitor.libs | ||||
|                 accessorLocal.Write(position, value); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| using Microsoft.Win32; | ||||
| using System.Runtime.InteropServices; | ||||
| 
 | ||||
| namespace llock.win | ||||
| namespace cmonitor.llock.win | ||||
| { | ||||
|     internal class Hook : IDisposable | ||||
|     { | ||||
| @@ -1,4 +1,4 @@ | ||||
| namespace llock.win | ||||
| namespace cmonitor.llock.win | ||||
| { | ||||
|     partial class MainForm | ||||
|     { | ||||
| @@ -3,7 +3,7 @@ using System.Diagnostics; | ||||
| using System.Runtime.InteropServices; | ||||
| using System.Text; | ||||
| 
 | ||||
| namespace llock.win | ||||
| namespace cmonitor.llock.win | ||||
| { | ||||
|     public partial class MainForm : Form | ||||
|     { | ||||
| @@ -1,4 +1,4 @@ | ||||
| namespace llock.win | ||||
| namespace cmonitor.llock.win | ||||
| { | ||||
|     internal static class Program | ||||
|     { | ||||
| Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB | 
| @@ -1,4 +1,4 @@ | ||||
| namespace message.win | ||||
| namespace cmonitor.message.win | ||||
| { | ||||
|     partial class MainForm | ||||
|     { | ||||
| @@ -1,6 +1,6 @@ | ||||
| using System.Runtime.InteropServices; | ||||
| 
 | ||||
| namespace message.win | ||||
| namespace cmonitor.message.win | ||||
| { | ||||
|     public partial class MainForm : Form | ||||
|     { | ||||
| @@ -1,4 +1,4 @@ | ||||
| namespace message.win | ||||
| namespace cmonitor.message.win | ||||
| { | ||||
|     internal static class Program | ||||
|     { | ||||
| @@ -8,7 +8,7 @@ | ||||
| // </auto-generated> | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| namespace message.win.Properties { | ||||
| namespace cmonitor.message.win.Properties { | ||||
|     using System; | ||||
|      | ||||
|      | ||||
| @@ -39,7 +39,7 @@ namespace message.win.Properties { | ||||
|         internal static global::System.Resources.ResourceManager ResourceManager { | ||||
|             get { | ||||
|                 if (object.ReferenceEquals(resourceMan, null)) { | ||||
|                     global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("message.win.Properties.Resources", typeof(Resources).Assembly); | ||||
|                     global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("cmonitor.message.win.Properties.Resources", typeof(Resources).Assembly); | ||||
|                     resourceMan = temp; | ||||
|                 } | ||||
|                 return resourceMan; | ||||
| Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB | 
| Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB | 
| @@ -1,4 +1,4 @@ | ||||
| namespace notify.win | ||||
| namespace cmonitor.notify.win | ||||
| { | ||||
|     partial class MainForm | ||||
|     { | ||||
| @@ -1,7 +1,7 @@ | ||||
| using System.Diagnostics; | ||||
| using System.Runtime.InteropServices; | ||||
| 
 | ||||
| namespace notify.win | ||||
| namespace cmonitor.notify.win | ||||
| { | ||||
|     public partial class MainForm : Form | ||||
|     { | ||||
| @@ -1,4 +1,4 @@ | ||||
| namespace notify.win | ||||
| namespace cmonitor.notify.win | ||||
| { | ||||
|     internal static class Program | ||||
|     { | ||||
| @@ -8,7 +8,7 @@ | ||||
| // </auto-generated> | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| namespace notify.win.Properties { | ||||
| namespace cmonitor.notify.win.Properties { | ||||
|     using System; | ||||
|      | ||||
|      | ||||
| @@ -39,7 +39,7 @@ namespace notify.win.Properties { | ||||
|         internal static global::System.Resources.ResourceManager ResourceManager { | ||||
|             get { | ||||
|                 if (object.ReferenceEquals(resourceMan, null)) { | ||||
|                     global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("notify.win.Properties.Resources", typeof(Resources).Assembly); | ||||
|                     global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("cmonitor.notify.win.Properties.Resources", typeof(Resources).Assembly); | ||||
|                     resourceMan = temp; | ||||
|                 } | ||||
|                 return resourceMan; | ||||
| Before Width: | Height: | Size: 316 KiB After Width: | Height: | Size: 316 KiB | 
| Before Width: | Height: | Size: 172 KiB After Width: | Height: | Size: 172 KiB | 
| Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 88 KiB | 
| Before Width: | Height: | Size: 173 KiB After Width: | Height: | Size: 173 KiB | 
| Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB | 
| Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB | 
| Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB | 
| Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB | 
| Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB | 
| Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB | 
| @@ -13,13 +13,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "cmonitor.libs", "cmonitor.l | ||||
| EndProject | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "cmonitor.install.win", "cmonitor.install.win\cmonitor.install.win.csproj", "{4EB9FFB0-B05C-4C4E-BD44-796715E47585}" | ||||
| EndProject | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "llock.win", "llock.win\llock.win.csproj", "{6F2602B3-221D-475D-B643-D54987605644}" | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "cmonitor.llock.win", "cmonitor.llock.win\cmonitor.llock.win.csproj", "{6F2602B3-221D-475D-B643-D54987605644}" | ||||
| EndProject | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "wallpaper.win", "wallpaper.win\wallpaper.win.csproj", "{41C61263-4F73-4C62-BD78-8C3612C8F98B}" | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "cmonitor.wallpaper.win", "cmonitor.wallpaper.win\cmonitor.wallpaper.win.csproj", "{41C61263-4F73-4C62-BD78-8C3612C8F98B}" | ||||
| EndProject | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "notify.win", "notify.win\notify.win.csproj", "{886D781B-9A41-4DD1-8B94-490AE6476E67}" | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "cmonitor.notify.win", "cmonitor.notify.win\cmonitor.notify.win.csproj", "{886D781B-9A41-4DD1-8B94-490AE6476E67}" | ||||
| EndProject | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "message.win", "message.win\message.win.csproj", "{BCA983E7-928F-4353-BF98-4ACCBB1B173E}" | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "cmonitor.message.win", "cmonitor.message.win\cmonitor.message.win.csproj", "{BCA983E7-928F-4353-BF98-4ACCBB1B173E}" | ||||
| EndProject | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "cmonitor.snatch.win", "cmonitor.snatch.win\cmonitor.snatch.win.csproj", "{5267B401-6818-407C-8323-E6C8A3CC01D6}" | ||||
| EndProject | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| using System.Runtime.InteropServices; | ||||
| 
 | ||||
| namespace wallpaper.win | ||||
| namespace cmonitor.wallpaper.win | ||||
| { | ||||
|     internal sealed class Hook : IDisposable | ||||
|     { | ||||
| @@ -1,4 +1,4 @@ | ||||
| namespace wallpaper.win | ||||
| namespace cmonitor.wallpaper.win | ||||
| { | ||||
|     partial class MainForm | ||||
|     { | ||||
| @@ -2,7 +2,7 @@ using cmonitor.libs; | ||||
| using System.Diagnostics; | ||||
| using System.Text; | ||||
| 
 | ||||
| namespace wallpaper.win | ||||
| namespace cmonitor.wallpaper.win | ||||
| { | ||||
|     public partial class MainForm : Form | ||||
|     { | ||||
| @@ -1,7 +1,7 @@ | ||||
| using System.Diagnostics; | ||||
| using System.Runtime.InteropServices; | ||||
| 
 | ||||
| namespace wallpaper.win | ||||
| namespace cmonitor.wallpaper.win | ||||
| { | ||||
|     internal sealed class MainFormSetParent | ||||
|     { | ||||
| @@ -1,4 +1,4 @@ | ||||
| namespace wallpaper.win | ||||
| namespace cmonitor.wallpaper.win | ||||
| { | ||||
|     internal static class Program | ||||
|     { | ||||
| Before Width: | Height: | Size: 515 KiB After Width: | Height: | Size: 515 KiB | 
| Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB | 
| @@ -115,7 +115,7 @@ export default { | ||||
|             }).then(() => { | ||||
|                 state.loading = true; | ||||
|                 const names = _devices.map(c => c.MachineName); | ||||
|                 const fn = state.recoedData ? play(names, state.recoedData) : exec(names, [`start message.win.exe "${state.prev}" ${state.sec}`]); | ||||
|                 const fn = state.recoedData ? play(names, state.recoedData) : exec(names, [`start cmonitor.message.win.exe "${state.prev}" ${state.sec}`]); | ||||
|                 fn.then((res) => { | ||||
|                     if (res) { | ||||
|                         ElMessage.success('操作成功'); | ||||
|   | ||||
| @@ -6,7 +6,7 @@ export default { | ||||
|     state: { | ||||
|         shareSnatch: { | ||||
|             showTemplate: false, | ||||
|             showUse: true, | ||||
|             showUse: false, | ||||
|             answers: [] | ||||
|         } | ||||
|     }, | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <template> | ||||
|     <div class="snatchs-items-wrap-info flex flex-nowrap flex-column"> | ||||
|         <div class="flex-1"> | ||||
|             <div class="prevs-wrap"> | ||||
|             <div class="prevs-wrap scrollbar-1"> | ||||
|                 <ul> | ||||
|                     <template v-for="(group,index) in state.answers" :key="index"> | ||||
|                         <li> | ||||
| @@ -11,22 +11,32 @@ | ||||
|                                 </dt> | ||||
|                                 <dd class="right"> | ||||
|                                     <el-row class="w-100"> | ||||
|                                         <el-col :span="8"> | ||||
|                                         <el-col :span="6"> | ||||
|                                             <el-form-item class="t-c" label-width="0"> | ||||
|                                                 <template v-if="group.Question.Cate == 1"> | ||||
|                                                     {{state.types[group.Question.Type]}} | ||||
|                                                 </template> | ||||
|                                                 <template v-else> | ||||
|                                                     {{ state.cates[group.Question.Cate]}} | ||||
|                                                 </template> | ||||
|                                             </el-form-item> | ||||
|                                         </el-col> | ||||
|                                         <el-col :span="6"> | ||||
|                                             <el-form-item class="t-c" label="参与" label-width="4rem">{{group.Question.Join}}</el-form-item> | ||||
|                                         </el-col> | ||||
|                                         <template v-if="group.Question.Cate ==1"> | ||||
|                                             <el-col :span="8"> | ||||
|                                             <el-col :span="6"> | ||||
|                                                 <el-form-item class="t-c" label="正确" label-width="4rem">{{group.Question.Right}}</el-form-item> | ||||
|                                             </el-col> | ||||
|                                             <el-col :span="8"> | ||||
|                                             <el-col :span="6"> | ||||
|                                                 <el-form-item class="t-c" label="错误" label-width="4rem">{{group.Question.Wrong}}</el-form-item> | ||||
|                                             </el-col> | ||||
|                                         </template> | ||||
|                                         <template v-else> | ||||
|                                             <el-col :span="8"> | ||||
|                                             <el-col :span="6"> | ||||
|                                                 <el-form-item class="t-c" label="已选" label-width="4rem">{{group.Question.Right}}</el-form-item> | ||||
|                                             </el-col> | ||||
|                                             <el-col :span="8"> | ||||
|                                             <el-col :span="6"> | ||||
|                                                 <el-form-item class="t-c" label="未选" label-width="4rem">{{group.Question.Wrong}}</el-form-item> | ||||
|                                             </el-col> | ||||
|                                         </template> | ||||
| @@ -150,6 +160,7 @@ export default { | ||||
|         &>ul>li { | ||||
|             border: 1px solid #ddd; | ||||
|             border-radius: 0.4rem; | ||||
|             margin-bottom: 0.6rem; | ||||
|  | ||||
|             dd { | ||||
|                 border-top: 1px solid #ddd; | ||||
|   | ||||
| @@ -88,7 +88,7 @@ | ||||
| <script> | ||||
| import { reactive, ref } from '@vue/reactivity'; | ||||
| import { computed, onMounted } from '@vue/runtime-core'; | ||||
| import { ElMessage } from 'element-plus'; | ||||
| import { ElMessage, ElMessageBox } from 'element-plus'; | ||||
| import { addQuestion, randomQuestion, updateQuestion } from '@/apis/snatch' | ||||
| import { injectGlobalData } from '@/views/provide'; | ||||
| import { injectPluginState } from '@/views/device/provide'; | ||||
| @@ -167,7 +167,17 @@ export default { | ||||
|                 return arr; | ||||
|             }, []).join('') : json.Correct.replace(/^\s|\s$/g, ''); | ||||
|         } | ||||
|  | ||||
|         const handleEditSubmit = () => { | ||||
|             ElMessageBox.confirm('确定以当前编辑好的题目开始吗?', '提示', { | ||||
|                 confirmButtonText: '确定', | ||||
|                 cancelButtonText: '取消', | ||||
|                 type: 'warning', | ||||
|             }).then(() => { | ||||
|                 handleEdit(); | ||||
|             }).catch(() => { }); | ||||
|         } | ||||
|         const handleEdit = () => { | ||||
|             formDom.value.validate((valid) => { | ||||
|                 if (!valid) { | ||||
|                     return; | ||||
| @@ -224,7 +234,17 @@ export default { | ||||
|  | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         const handleRandomSubmit = () => { | ||||
|             ElMessageBox.confirm('随机开始,则每台设备都以随机题目方式启动,确定以随机方式开始吗?', '提示', { | ||||
|                 confirmButtonText: '确定', | ||||
|                 cancelButtonText: '取消', | ||||
|                 type: 'warning', | ||||
|             }).then(() => { | ||||
|                 handleRandom(); | ||||
|             }).catch(() => { }); | ||||
|         } | ||||
|         const handleRandom = () => { | ||||
|             const names = pluginState.value.command.devices.map(c => c.MachineName); | ||||
|             state.loading = true; | ||||
|             randomQuestion(names.length).then((questions) => { | ||||
|   | ||||
| @@ -194,6 +194,7 @@ namespace cmonitor | ||||
|             else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton<INotify, NotifyMacOS>(); | ||||
|  | ||||
|             serviceCollection.AddSingleton<ScreenReport>(); | ||||
|             serviceCollection.AddSingleton<ScreenShare>(); | ||||
|             if (OperatingSystem.IsWindows()) serviceCollection.AddSingleton<IScreen, ScreenWindows>(); | ||||
|             else if (OperatingSystem.IsLinux()) serviceCollection.AddSingleton<IScreen, ScreenLinux>(); | ||||
|             else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton<IScreen, ScreenMacOS>(); | ||||
|   | ||||
| @@ -16,7 +16,7 @@ namespace cmonitor.client.reports.llock | ||||
|             if (value) | ||||
|             { | ||||
|                 CommandHelper.Windows(string.Empty, new string[] { | ||||
|                         $"start llock.win.exe {config.ShareMemoryKey} {config.ShareMemoryLength} {config.ShareMemoryItemSize} {Config.ShareMemoryLLockIndex}" | ||||
|                         $"start cmonitor.llock.win.exe {config.ShareMemoryKey} {config.ShareMemoryLength} {config.ShareMemoryItemSize} {Config.ShareMemoryLLockIndex}" | ||||
|                     }); | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -14,7 +14,7 @@ namespace cmonitor.client.reports.notify | ||||
|             Task.Run(() => | ||||
|             { | ||||
|                 CommandHelper.Windows(string.Empty, new string[] { | ||||
|                         $"start notify.win.exe {notify.Speed} \"{notify.Msg}\" {notify.Star1} {notify.Star2} {notify.Star3}" | ||||
|                         $"start cmonitor.notify.win.exe {notify.Speed} \"{notify.Msg}\" {notify.Star1} {notify.Star2} {notify.Star3}" | ||||
|                     }); | ||||
|             }); | ||||
|         } | ||||
|   | ||||
| @@ -19,8 +19,5 @@ namespace cmonitor.client.reports.screen | ||||
|         public void WakeUp(); | ||||
|  | ||||
|  | ||||
|         public void ScreenShareState(ScreenShareStates screenShareState); | ||||
|         public void ScreenShare(Memory<byte> data); | ||||
|  | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -45,11 +45,5 @@ namespace cmonitor.client.reports.screen | ||||
|         } | ||||
|  | ||||
|  | ||||
|         public void ScreenShareState(ScreenShareStates screenShareState) | ||||
|         { | ||||
|         } | ||||
|         public void ScreenShare(Memory<byte> data) | ||||
|         { | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -45,11 +45,5 @@ namespace cmonitor.client.reports.screen | ||||
|         } | ||||
|  | ||||
|  | ||||
|         public void ScreenShareState(ScreenShareStates screenShareState) | ||||
|         { | ||||
|         } | ||||
|         public void ScreenShare(Memory<byte> data) | ||||
|         { | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -3,7 +3,6 @@ using common.libs; | ||||
| using cmonitor.service.messengers.screen; | ||||
| using MemoryPack; | ||||
| using common.libs.helpers; | ||||
| using System.Threading.Tasks; | ||||
|  | ||||
| namespace cmonitor.client.reports.screen | ||||
| { | ||||
| @@ -57,20 +56,11 @@ namespace cmonitor.client.reports.screen | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         public void SetDisplayState(bool onState) | ||||
|         { | ||||
|             screen.SetDisplayState(onState); | ||||
|         } | ||||
|  | ||||
|         public void SetScreenShareState(ScreenShareStates screenShareState) | ||||
|         { | ||||
|             screen.ScreenShareState(screenShareState); | ||||
|         } | ||||
|         public void SetScreenShareData(Memory<byte> data) | ||||
|         { | ||||
|             screen.ScreenShare(data); | ||||
|         } | ||||
|  | ||||
|         private ScreenReportType screenReportType = ScreenReportType.Full; | ||||
|         private ScreenReportFullType screenReportFullType = ScreenReportFullType.Full | ScreenReportFullType.Trim; | ||||
| @@ -235,10 +225,5 @@ namespace cmonitor.client.reports.screen | ||||
|         public int H { get; set; } | ||||
|     } | ||||
|  | ||||
|     public enum ScreenShareStates : byte | ||||
|     { | ||||
|         None = 0, | ||||
|         Sender = 1, | ||||
|         Receiver = 2 | ||||
|     } | ||||
|     | ||||
| } | ||||
|   | ||||
							
								
								
									
										108
									
								
								cmonitor/client/reports/screen/ScreenShare.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,108 @@ | ||||
| using cmonitor.libs; | ||||
| using cmonitor.service; | ||||
| using cmonitor.service.messengers.screen; | ||||
| using cmonitor.service.messengers.sign; | ||||
| using MemoryPack; | ||||
| using System.Collections.Concurrent; | ||||
| using static System.Runtime.InteropServices.JavaScript.JSType; | ||||
|  | ||||
| namespace cmonitor.client.reports.screen | ||||
| { | ||||
|     public sealed class ScreenShare | ||||
|     { | ||||
|         private readonly Config config; | ||||
|         private readonly ClientConfig clientConfig; | ||||
|         private readonly SignCaching signCaching; | ||||
|         private readonly MessengerSender messengerSender; | ||||
|  | ||||
|         private readonly ConcurrentDictionary<string, string[]> shareMap = new ConcurrentDictionary<string, string[]>(); | ||||
|  | ||||
|         public ScreenShare(Config config, ClientConfig clientConfig, SignCaching signCaching, MessengerSender messengerSender) | ||||
|         { | ||||
|             this.config = config; | ||||
|             this.clientConfig = clientConfig; | ||||
|             this.signCaching = signCaching; | ||||
|             this.messengerSender = messengerSender; | ||||
|  | ||||
|             if (config.IsCLient) | ||||
|             { | ||||
|                 Init(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|  | ||||
|         private ShareMemory shareMemory; | ||||
|         private void Init() | ||||
|         { | ||||
|             shareMemory = new ShareMemory($"{config.ShareMemoryKey}/screen", 1, 2 * 1024 * 1024); | ||||
|             shareMemory.InitGlobal(); | ||||
|         } | ||||
|         public async Task SetState(string machineName, ScreenShareSetupInfo screenShareSetupInfo) | ||||
|         { | ||||
|             if (config.IsCLient) | ||||
|             { | ||||
|                 clientConfig.ScreenShareState = screenShareSetupInfo.State; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 if (screenShareSetupInfo.MachineNames.Length > 0) | ||||
|                 { | ||||
|                     shareMap.AddOrUpdate(machineName, screenShareSetupInfo.MachineNames, (a, b) => screenShareSetupInfo.MachineNames); | ||||
|                     byte[] bytes = MemoryPackSerializer.Serialize(new ScreenShareSetupInfo { State = ScreenShareStates.Receiver }); | ||||
|                     foreach (string name in screenShareSetupInfo.MachineNames) | ||||
|                     { | ||||
|                         if (signCaching.Get(name, out SignCacheInfo sign) && sign.Connected) | ||||
|                         { | ||||
|                             await messengerSender.SendOnly(new MessageRequestWrap | ||||
|                             { | ||||
|                                 Connection = sign.Connection, | ||||
|                                 MessengerId = (ushort)ScreenMessengerIds.ScreenShareState, | ||||
|                                 Payload = bytes, | ||||
|                             }); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         public void SetData(Memory<byte> data) | ||||
|         { | ||||
|             shareMemory.Update(0, data.Span); | ||||
|         } | ||||
|         public async Task<bool> SendData(string machineName, Memory<byte> data) | ||||
|         { | ||||
|             if (shareMap.TryGetValue(machineName, out string[] names)) | ||||
|             { | ||||
|                 foreach (string name in names) | ||||
|                 { | ||||
|                     if (signCaching.Get(name, out SignCacheInfo sign) && sign.Connected) | ||||
|                     { | ||||
|                         await messengerSender.SendOnly(new MessageRequestWrap | ||||
|                         { | ||||
|                             Connection = sign.Connection, | ||||
|                             MessengerId = (ushort)ScreenMessengerIds.ScreenShare, | ||||
|                             Payload = data, | ||||
|                         }); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public enum ScreenShareStates : byte | ||||
|     { | ||||
|         None = 0, | ||||
|         Sender = 1, | ||||
|         Receiver = 2 | ||||
|     } | ||||
|  | ||||
|     [MemoryPackable] | ||||
|     public sealed partial class ScreenShareSetupInfo | ||||
|     { | ||||
|         public ScreenShareStates State { get; set; } | ||||
|         public string[] MachineNames { get; set; } | ||||
|     } | ||||
| } | ||||
| @@ -1,7 +1,6 @@ | ||||
| using common.libs; | ||||
| using common.libs.helpers; | ||||
| using common.libs.winapis; | ||||
| using System.IO.MemoryMappedFiles; | ||||
|  | ||||
| namespace cmonitor.client.reports.screen | ||||
| { | ||||
| @@ -80,29 +79,5 @@ namespace cmonitor.client.reports.screen | ||||
|             } | ||||
|         } | ||||
|  | ||||
|  | ||||
|         MemoryMappedFile mmf; | ||||
|         MemoryMappedViewAccessor accessor; | ||||
|         byte[] shareScreenBytes = new byte[1 * 1024 * 1024]; | ||||
|         private void ScreenShareInit() | ||||
|         { | ||||
|             if (OperatingSystem.IsWindows()) | ||||
|             { | ||||
|                // mmf = MemoryMappedFile.CreateOrOpen($"{config.ShareMemoryKey}/screen", shareScreenBytes.Length); | ||||
|                // accessor = mmf.CreateViewAccessor(); | ||||
|             } | ||||
|         } | ||||
|         public void ScreenShareState(ScreenShareStates screenShareState) | ||||
|         { | ||||
|             //clientConfig.ScreenShareState = screenShareState; | ||||
|         } | ||||
|         public void ScreenShare(Memory<byte> data) | ||||
|         { | ||||
|             if (data.Length > 0 && data.Length <= shareScreenBytes.Length && accessor != null) | ||||
|             { | ||||
|                 data.CopyTo(shareScreenBytes); | ||||
|                 accessor.WriteArray(0, shareScreenBytes, 0, data.Length); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -14,7 +14,7 @@ namespace cmonitor.client.reports.wallpaper | ||||
|             if (value) | ||||
|             { | ||||
|                 CommandHelper.Windows(string.Empty, new string[] { | ||||
|                         $"start wallpaper.win.exe \"{url}\" {config.ShareMemoryKey} {config.ShareMemoryLength} {config.ShareMemoryItemSize} {Config.ShareMemoryKeyBoardIndex} {Config.ShareMemoryWallpaperIndex}" | ||||
|                         $"start cmonitor.wallpaper.win.exe \"{url}\" {config.ShareMemoryKey} {config.ShareMemoryLength} {config.ShareMemoryItemSize} {Config.ShareMemoryKeyBoardIndex} {Config.ShareMemoryWallpaperIndex}" | ||||
|                     }); | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -11,13 +11,16 @@ namespace cmonitor.service.messengers.screen | ||||
|         private readonly IClientServer clientServer; | ||||
|         private readonly Config config; | ||||
|         private readonly SignCaching signCaching; | ||||
|         private readonly ScreenShare screenShare; | ||||
|  | ||||
|         public ScreenMessenger(ScreenReport screenReport, IClientServer clientServer, Config config, SignCaching signCaching) | ||||
|  | ||||
|         public ScreenMessenger(ScreenReport screenReport, IClientServer clientServer, Config config, SignCaching signCaching, ScreenShare screenShare) | ||||
|         { | ||||
|             this.screenReport = screenReport; | ||||
|             this.clientServer = clientServer; | ||||
|             this.config = config; | ||||
|             this.signCaching = signCaching; | ||||
|             this.screenShare = screenShare; | ||||
|         } | ||||
|  | ||||
|         [MessengerId((ushort)ScreenMessengerIds.CaptureFull)] | ||||
| @@ -32,8 +35,12 @@ namespace cmonitor.service.messengers.screen | ||||
|         } | ||||
|  | ||||
|         [MessengerId((ushort)ScreenMessengerIds.CaptureFullReport)] | ||||
|         public void CaptureFullReport(IConnection connection) | ||||
|         public async Task CaptureFullReport(IConnection connection) | ||||
|         { | ||||
|             if (await screenShare.SendData(connection.Name, connection.ReceiveRequestWrap.Payload)) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             if (signCaching.Get(connection.Name, out SignCacheInfo cache)) | ||||
|             { | ||||
|                 if (cache.Version == config.Version) | ||||
| @@ -59,6 +66,7 @@ namespace cmonitor.service.messengers.screen | ||||
|         { | ||||
|             screenReport.SetCaptureRegion(); | ||||
|         } | ||||
|  | ||||
|         [MessengerId((ushort)ScreenMessengerIds.CaptureRegionReport)] | ||||
|         public void CaptureRegionReport(IConnection connection) | ||||
|         { | ||||
| @@ -87,14 +95,16 @@ namespace cmonitor.service.messengers.screen | ||||
|         [MessengerId((ushort)ScreenMessengerIds.ScreenShare)] | ||||
|         public void ScreenShare(IConnection connection) | ||||
|         { | ||||
|             screenReport.SetScreenShareData(connection.ReceiveRequestWrap.Payload); | ||||
|             screenShare.SetData(connection.ReceiveRequestWrap.Payload); | ||||
|         } | ||||
|  | ||||
|         [MessengerId((ushort)ScreenMessengerIds.ScreenShareState)] | ||||
|         public void ScreenShareState(IConnection connection) | ||||
|         public async Task ScreenShareState(IConnection connection) | ||||
|         { | ||||
|             screenReport.SetScreenShareState((ScreenShareStates)connection.ReceiveRequestWrap.Payload.Span[0]); | ||||
|             ScreenShareSetupInfo screenShareSetupInfo = MemoryPackSerializer.Deserialize<ScreenShareSetupInfo>(connection.ReceiveRequestWrap.Payload.Span); | ||||
|             await screenShare.SetState(connection.Name, screenShareSetupInfo); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
 snltty
					snltty