From 26eb2ea6b7226a5f4609d4d946c78eb04715f7f0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 22 Sep 2025 12:34:54 +0000 Subject: [PATCH 1/4] Initial plan From 60ced4295d0113987570c5f53211494236bb18b1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 22 Sep 2025 12:46:02 +0000 Subject: [PATCH 2/4] Implement multi-user support for desktop server Co-authored-by: km <39051822+km@users.noreply.github.com> --- .../META-INF/MANIFEST.MF | 5 - .../com/company/Config.class | Bin 343 -> 274 bytes .../com/company/ConfigurationManager$1.class | Bin 693 -> 591 bytes .../com/company/ConfigurationManager.class | Bin 3582 -> 3109 bytes .../com/company/Main.class | Bin 3086 -> 3428 bytes .../components/CPU.class | Bin 2021 -> 1884 bytes .../components/Component.class | Bin 882 -> 739 bytes .../components/ComponentManager.class | Bin 3626 -> 4164 bytes .../components/GPU.class | Bin 1725 -> 1800 bytes .../components/PhysicalDisk.class | Bin 2929 -> 2507 bytes .../components/Ram.class | Bin 1131 -> 1012 bytes .../production/RemoteMonitor Desktop/main.iml | 11 -- .../networking/ClientHandler.class | Bin 0 -> 5217 bytes .../networking/KeywordGenerator.class | Bin 1268 -> 1096 bytes .../networking/MultiUserServer.class | Bin 0 -> 5067 bytes .../networking/Server.class | Bin 3913 -> 3505 bytes .../out/production/main/.idea/.gitignore | 8 - .../out/production/main/.idea/misc.xml | 6 - .../out/production/main/.idea/modules.xml | 8 - .../out/production/main/.idea/vcs.xml | 6 - .../out/production/main/main.iml | 11 -- .../src/main/java/com/company/Main.java | 64 +++---- .../java/components/ComponentManager.java | 57 +++++-- .../src/main/java/components/GPU.java | 23 ++- .../main/java/components/PhysicalDisk.java | 11 +- .../main/java/networking/ClientHandler.java | 157 ++++++++++++++++++ .../main/java/networking/MultiUserServer.java | 145 ++++++++++++++++ 27 files changed, 408 insertions(+), 104 deletions(-) delete mode 100644 RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/META-INF/MANIFEST.MF delete mode 100644 RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/main.iml create mode 100644 RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/networking/ClientHandler.class create mode 100644 RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/networking/MultiUserServer.class delete mode 100644 RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/out/production/main/.idea/.gitignore delete mode 100644 RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/out/production/main/.idea/misc.xml delete mode 100644 RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/out/production/main/.idea/modules.xml delete mode 100644 RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/out/production/main/.idea/vcs.xml delete mode 100644 RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/out/production/main/main.iml create mode 100644 RemoteMonitor Desktop/src/main/java/networking/ClientHandler.java create mode 100644 RemoteMonitor Desktop/src/main/java/networking/MultiUserServer.java diff --git a/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/META-INF/MANIFEST.MF b/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/META-INF/MANIFEST.MF deleted file mode 100644 index 6a25437..0000000 --- a/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/META-INF/MANIFEST.MF +++ /dev/null @@ -1,5 +0,0 @@ -Manifest-Version: 1.0 -Main-Class: com.company.Main -Class-Path: C:\Users\omar\Desktop\RemoteMonitor\RemoteMonitor Desktop\sr - c\main\java\com\company\Main.java - diff --git a/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/com/company/Config.class b/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/com/company/Config.class index e5342d2a7c6a3411bd77546d0c1a6f9d8c3ce718..027fc68ade00e649e2626a957a51b36c8c7c0859 100644 GIT binary patch delta 62 zcmcc4G>M7p)W2Q(7#J9A8H6TsO`CYxOGB1{5eOL=Shcn@Fm41g7#aA1BpX->Oiap24FM613@jxXnZ=9@B0kCa zx%xm{keFAg@0_2PmYHrnah{KrJ_92VGBB`eZD(NI2xKrZ@B>LUupl#o0FccCQNSR` OAOz$wG6;iJi2wj$8XCp` diff --git a/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/com/company/ConfigurationManager$1.class b/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/com/company/ConfigurationManager$1.class index 65c076a79a858f8166eb945658cd298fd97623cd..de2e9acc40dd9e25bcfac0ef4228ac1d909c1e2f 100644 GIT binary patch delta 199 zcmdnWdY(o6)W2Q(7#J9A8Duyam>8JZ8CZB2SQ*$R`l?U-p~K6?z`?-D&cMaPz|Fuj zQQVl7kwI0%XJUZD#OZRAEg72`#U}4%RArW6kevLK(Xo^XsGNa;Q9uA>1c(L1+zh-x znh(fQ0$RWXq`9=Tw=ytlZD(NL2v)-nB-y}fy@2`zfIKD!K?Wf(EzBSSq*)k58N?Z+ Sz#^gy(m8JZ8CZB2SQ*$D85Ae}R-8DSpN*Y?gONdL;(7%p z6~l?EoMnZ4@{<#D!V-%z6O(dMLqG&014~IpW-%j!%EWbw%qoV~6K(W_85sn8Q%f@P zQvwo;5_3~aQj3ZwzHVidm|V!H$}GhoJ$WXhV?8_2P7q)OVpaxDAdd^kvIO!$;;dTR z85lPL8B7e^K#~ot%!`2s$QFYrVBlro1M)zc`56R&@`4~X(6j~tppX!d!^9xWAOfaE eftnZ?SQx|^BpGDDBH{uJvOoqGP#-&x1_A&=eJErA diff --git a/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/com/company/ConfigurationManager.class b/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/com/company/ConfigurationManager.class index 4e1fde1a959b8d9474357bd87635491a43adca6b..e55e2be3623e025421f347d775d9ef93879d018a 100644 GIT binary patch delta 503 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 literal 3086 zcmai0`*$2w9sk^9li6;jO*?66L)x;1(k2D6R8b*8gf4_GBz}@j5?94JV z+jc<(QBdCRM|moW^@R$;CMM$X2M>qi@f`ji4vL>UyGeH41%H^iukZanKHt~<=YN*| z2H+-qm_i3S4J1r-p<7_%X?aFwT3F&wO>up!b;J6Bkjwf9M>jlz{R9W9U<;<1?89BZ;Aw4;(f)q@x#72Pu z&CK_d7loPZ%5;^gS5x%~Z1Ple)(_?#s+m{8nHq;JCN9EOfz+&u#(i75xst%JEK}&zln=6AYhRCh#$~U+LzNOJ520c;d8sHP*5QS3uz6}E`h&*>6~}U4~j9EDGVcH;A#{5@fCr-*zD%}G`FO=xpdT)Hg*h6S`3S8OnePr z7uZ^q^NO-;8BICS9A{x9=^25&ZSLmU0Bu3wTFvb`fjw>Rw7H_89yM`2zA4Z}d3Dd6 z)cfBuaijLk2Kuayfhy!m7GwBYeV#ROGj0*+al+MOZD^yI1HR7y^%w)U;-G03?rw}k_YP6HmEi27`+{A>IpP(-aNgO5#y(-gzx~HtdD21aqW*~3kI8HRXHjX>y z5(%YC0Gq(CW!mV_$t0$Dlyx1({|Zx8NNX87n5Ipf)Z)7%|F+Qgv_{`C@m<_Wq|OFT zq}n^Co%KoFEwDRZwrv%Lr^>EdNrzf!Y)<5-qdAqfV?C0X5!f{*9haK$gk&|1^rDfh zz<{Zvt^>2+gmx`V6`?vsyN(eex|0b=COT<{hlf+zh&dCEPLdwm^+Q!l=p^PDtbRD` z$s)1egQ5vfhf$Bt*T65SAgUz63^%46ui&2zHTr>x5KNvVMMo@0M0%hx?6Pw*$ZKbL zwj$mJ&IoK<^E~-#JPwo{x1fR~&M_J7BGtcFpd(`^@jboaQdAi~(B_twI zA)w3O>Y_RJ>)Wg%PcmfULaiA-ZQ>a`%dl4Gl>Pr>Xhj!Z$od6J>>YPJb*NmNQNeLJ z<8sG}>+hrt9KEh@CZaiq4zb1?+ktKxqvTYKn}^j3CBwZIEv#tcEp=aCmBB38_O)>X z%Rd95rQHZz+N1-cwuOd_H?H=gdIJ*Jq3?ZBf8v$(`AFLH6S7n{Id#i9Ta|R74h_7$ zQj_EMx_V;Z!pZ@Qb?)%$0bQB*%Ym)Nn0t&O4b`v?R;tDt6@^hCOA{)Z^9x}TzZcjU zqt0%-)*X(Fq(xe{H;zgCfh_ACEnfdgpkJiJ#wt+1tO}{#ZoHSmpYgtd4|EByvS6&G zisPN}=T)ZGPzfM=#F(@rKd1=2+?aB8!kV53rB`rOxO?39=gXzhR&O`#G+jJiDXBK( zjXqzgqOB~l(slDJk93fkBQ`7Nwh?lrphnI0bsd!nuLPlNO`(zQu zGR)}(Y#3igFUL(2%dn=esA4m}ZTz+`;F3dER&nWjxZL9UDvm41OZY0Vy0v`?--wr2 zRWUL}GLAPa@nNV*I6qLu*m)e}?DmmFf8ryI^e3!CRUA2wt2OgUl4(Ku_w6d~h{-qT zle>6w0X=#u_4M=i_0;B6kBTFi&R+QZR+`iq!*D0I#sG9;17DZD=woZx%l{SFOr5u2 zjL*9hq&bOg>=zfa(hs159V}ow@iZh%pg3(y71UmL7R~7gb lZTU6nI`A9(mg8ow-=$)|i~sM$|36}ZCn@eOVu?2P{}(B%J)!^r diff --git a/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/components/CPU.class b/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/components/CPU.class index 243cdbdc380331b9b065617997629d1617b53b26..530bae73d149baa06d20dcd97bbc07b3d8a1d41d 100644 GIT binary patch delta 215 zcmaFLe}|9j)W2Q(7#J9A8R|E3yOecIfr3m7H4L>tnhU5)he3{^jzJOtIUXN8 delta 351 zcmcb^_mrRO)W2Q(7#J8F8Jae7y<^c8^2tw5%n3^@%1lhkNeuxJj0`L#8JWe53<5sM z`MCx8d8v6N#rn}I8fzWHr0BBN*}n&Y6e@VN__?KPh<u&;kH) Cr5IQM delta 377 zcmaFN`iYI})W2Q(7#J8F8T2-CX)ziL`Q#@j=7c2{WhN%&q=tY9Mh2FWjLc$21~H%H z{M>^4ywtpsVtr>A(|WQI<0(d`$$uH8>zNo7foAbBFoQ`J27VwEU{C_`co-OgqyU35 zg9?ylWKd;L1Ck0rwmt(BSdLX|3xmLVpa8@WHn5-&l4e%8W_1P)xMoJUW|0l`Xu8F) o>ej?+wFJ7=Qdl)>F=)fBMz~vgE!bvtknbT5m&2-C2dqpN0Qj3KS^xk5 diff --git a/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/components/ComponentManager.class b/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/components/ComponentManager.class index 5c471701fe7c4352151c65388f2bc9bef54ca5d5..15bf79abb88da0dcdd97d0cc6531344ab2f3c4fe 100644 GIT binary patch literal 4164 zcmb7HTXa-c8UA)=GAEfFE)7i62?%NBlKVilK{H4RX-EbV2uwnRQ1xVTk{mKQXE^5! zC3q<+)@!vY+JYApt7)}fKu92|we^Bht4}`qplkW!t1qs_LgTm3nMo!g#VXXFruT>GjgXFcfu|>QjBkw~3YrNBET_YW9v2AU<({S7{DtrO!RIJB4 z1cJkvtRp4N6HB_dv|yu(DoIm3XgH%zDIUQ)6>L(m8CwK4@wl;!Z4K#;We;iTQQeH4 zaCDP1C$=x?4|u>~onG4_jr+gU@i0|XtEfS(KzQCA0`cmaWhIPRgL*nP&k<|Qd)c8S z^;oB%L14#nhge30f|$T6%Na3Z$#KWk#}ej{6-FZhvUya+yYOy-GFsZ9*@I7Mwk}Z1 z6MGyZxusZsuVuh-Z7t;*mf5L|>vp^hP1vE}Ju2RdX8P*wu`y;;*luf?5hLZaQVYXa zPOXaqDW&gJ32usBL5?RF%cN`BIs;mdjb+%476p4$wBiZkZ6P=D;TUIV4$+pR`ZI+3MFV(PO-L_%6N!Qky z>0$I^P=$^mrVPW|r8^GGion`D6ns%Gd4}WVEOR3&44e?C7}G}eR?AFjZlB?faOAie ziO_GBR3upo!9*?vWC*Oih|Vb9vOFx zl$Mr2RlwpAT?mMdzBvdhI3=+CzVIMdzn7&PK|Cwb`Mio3b$_d?mspyqPv zBreJel+9{fRPY^|Aj3OsS;J{PHtbkttes65mt^t1gzu?%5#Of(*V@PRMF!;zUh;Is zn2-j%ByfBQAKYut+gVvckw9tE7&bLGD{qBId?{XxnK< zu$6Zoz1wM+`ho1&fNu9_18J_T@Lb)cWpeXU-^VTKG%H2Y%GxP?uOSH|t@+C`_ateQ zC}SnsV_B}lyDHPAyCc@1vnqsZVO+R66E~_5|#*mPDHDgPA8ds@e)k)dDdpz zmR%(uc7~QV&am87F&I^%xk{AaRe|+O5XfxLQM^Xj{V$5@gUOCWm1U;KYdmSM3p6bD z_q=9(kVI0qQ_o(ia7ys2rNu9n;)(x_fZ8v}?0=u+G+~;$-I~@MM|TwbPGIvrFoq3N3>vw;Z4%pW z;xU1)!a1|+K%R0}bFl6f)ViB^TwnshKs{&mbF&+0Ybp*jg(9Iy@ny8vUPI*!_8+Z} zgl?j%2(P2NZf>${^6H}{qCi!oxsY`RPwWqZ^-r7hK*<@xb_iz$N0xV=ccX)5P#)8_7k4)B~;A9MzMl21-s|IAZw?XCBZ#AMMC@= ziVztE{cG-^cx9e4v`B_Pp7dm%^e)yaI5$iCN*5CgZYXpG`~Ew4;0}sr=_=03yrnfv zwV&n_j%msporml5BS=JaG9x@ZtmVLi!~U-NNnDti{f8giC23Adns53v;Yoapq-!Se z?JE@Rhj9x^IX=i*(9M7y!X_L>3zBF<4?57xog@78d9GZG;9Z1i#vMfON(1G92YnGk zew|>@izydqoWUh#`*%C*sE~Ru%f2$#^8ns_1N&+G0Qea>ga<15M<0Y(369fzxn6`T nxXOMDUGsBN-SpZSul?M$QI}*%LN^z(TMFJ% z1jP#qa`1wP7Q7T4#}UUVQ|dU%_z6EaesOe0e}EsH;d7^2-`#{vXLNSYdEc}9Jn!W> zXZMGO&uW!x|6KVNKrcSMq|^xk84oht6w9V_*^HJkjbQ)ws2iKH)q^z{;QNId_7FcV z)UycxT-fLhVVegcwlnN#3iA^}4R<-aq(?j$!cN}rY+%EDN~~p%@^fNLH@nG;WpqY51z&|4Ap6M zTFAl)6XPc3KkyOVJo$aGJ@K!B7`oCRg7L zSd4qHwC^L&Q`1!QU-@#DXw62&-S2Ky=keN?q5(KHT zSiwX#o6xmj!pLTV{WSIP>#j|WF1*L!*~MBLO84#+65dzv0j6b~w>IVi@2a@El0XBQ zjF#`yRm0E>86We%lxF7)Lx5jb0=&yzTm3AZUI(6|(SSNI6xRi=yKnVQ0qj>ubOC?x z({8OGbc(CQmO0$dZ~-07U!!Ioq0!b=;vD)N_zr_DWjA~o56@wT10zR8Hna4jO>HYt z*Aq1`kLYMy89(B8mi^Jo*tLv%?GhE>#9=!3cmO_r-dkO$LpK5#L_Nl+at*6tpb_tq zou*Ii3*3QU$o`IIJWu4Ubf%Nogd;dgK|VxR$)mpT0$wCUH$6ROD=-L-m&kKay!{ZELQhg7@8B~&!WCapC6ltA>KC|?vCFcKu2otq1*&;@n zMUJ31&tktNs6c`OYf(XSJM|VM?K*Hf*3;kYPWm_8MXGJUHf+Q&I&Bpjh+}DR3cNtw z_L6%VZ<0ramSnWLt%P$Cij3F-{EMh4I@Hi4-YT`Xmo~v-wa+6@du@hWs4gmR!m>3b zOLf}o0NE=z1bj&hhh4OSh(+&)3q5vaRmE_nB3#tfDZFiK_>N6FLni}-W;jRVEbTR* MkoOTj!A1E01@{+GmjD0& diff --git a/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/components/GPU.class b/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/components/GPU.class index 69e86e74457de331303245c8328491a7d18ed6ad..1b85ccf90cc1dc9a6fc27f19958c7e51f2b2745e 100644 GIT binary patch delta 646 zcmZXQOHWf#6otQYZ)+c1IsgYIK7!ULRB2J@qzFoF@l{I|i-HPX%C*)M+R&Eh#7<32 zoZOL4j3Y;y5DSV?W1{K6AK_mxaY|y`eUNIL?6uE1Ykwzued>Pf^M3#R;WIEsZr%G# z+vCcW;>*SILxtWyFxN$xQG-*A*)O#|$7w~_9?}B#Pp$jpI1>g@&MKU1X1-!6dJ^}| zH8YeqSF)j4p|Y5_M!m$DbaBq$JQwVser)oRL4wPQuCldUv{ub>WmQI1%*B+Vw*!bj z$XLa4uCU@E#1(_949idXg1J<3am{|A5BE(o;la&ygBuN^vr;m%mX|qhy0~R<+y12w zIu;D>*nUUV{^7`aOcaZH&;nZJW1wx%ciJCM%Ihqle(87_VFmi0n+%zc92;PiS-Ci zIm#ObWGENRj3i!RI8#;P@jSdD1OmLd6Z`gZThk9%EXnM zi3|S%S1w2%21zik{iBTc)f&wtXYSm4=FBA`sc61@4yUi_tKv%b7WxyY} z#mbtLJ&EGZ@v<@3IrQ!G+Q(Z^HGa-!n4n?WT^v&u7%=bAO6oeAfq=9MWp zo&2C*D+krppb-Td)o?ihh11%Onu-&CxwccU?S{LpW^R6IMIzXhdRyj#SIwalrCy_W zBT3(x%WmGbST~V7-YH4vEVf{dfDPG`s*DzPQf+bpOX`qgz55@9ZON>d&BmOIxfnBP zf8(0P5ArcLzH)n?;%6NHAHn}iSd4kxB|OO$C0K~|vWH$OE9pgKVNz7|qE_wfv8up@ErP&pW%l5%Tek`l zRLn)tMxy?j)!A?{FFovKnRPiY(>D)W(_ARvc3OxCzimJDCU_BnYxV z4{P+26PdV6 delta 716 zcmZuuO-~b16g_X+&RDc00x4-z!4yJpAWX3dffPz?3uvK`=)h*hD>tjzH{F__niBVn}38GzWx6E1;7>T z9W>lg+nUV64A0-{;%J6}7t~B#|4u=vab~J~KbX?fN*D zXGoZ$Ux|zFYAD7K{#Vqp{a08_VXTVD1G=u@ zA;mBP6k`bC0?wlis~u>EP70)s+RUE14u)+s)o0c;00A0s{e#CQB?0jh%>l2ubZT?+ zf6Z}pozkt~vS;_5_oenMdKM6>==}w;<5}(Ko$c7tJW3^4ywtpsV*Q}RTcAp&2tiZ@Lxq(@<9-&ecuF{b~393?`feCC1 rtJW3 - - - - - - - - - - \ No newline at end of file diff --git a/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/networking/ClientHandler.class b/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/networking/ClientHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..336096622cedca6787c461e63475957955c33843 GIT binary patch literal 5217 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 literal 0 HcmV?d00001 diff --git a/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/networking/Server.class b/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/networking/Server.class index 85372e1d71e57f52875bc7fb0417ffcb29541798..ad3001b3f4c1112a6e82ac0d4a0c85ebc5678c1b 100644 GIT binary patch delta 541 zcmZ9G$uC1u6vn^%I=t7{*OrQiNE@M*svs5;Ls*y+u_F>2l7@yFN)!>Zg@~2KU08{j zYNn5>>cXNs-P`yxED>>@R8toBO!s%r_dPq+B02SycmmLbgeu!btK2?6=%1PiOa?uFZ%m8P~WG5mB%Ul@CivorF8?k*e$rN@pjPXX3S086^ z@@A8hZ<a|gjmbER8@CFtBOBDM@!ynp~k(|k8?Q#`~^C=Qp#ix7GUM;6YojXH9qd0F8p zrGapRrJRL%uceIb@g++iOYQR-x>?(u*}6n+D<{AOqX delta 978 zcmZ8eO-~b16g_X+GSlgV@?jyw1Wg2`7;F?wP&XneQK*RtYK#lw*iLkynVC$dh$aR% zE{riQ-pYkB2!1P4MMP9ol!eCMpz#;DHEN9aO^2qscr*9ich5QZ+*?}zu~q%_XK5Kg zA683hgM6YPV`ugJQQbB5lX>H?_%MXM(`JF8F=H9t8QUE*ty8IC!yPx=Jq(iRP=#Z= z9z%WBwk#v-nYJ}#oTbtngPNYm8jeU6WIW)Vaz~Hi8U=^$M9t_VGNbyqp33V)TPY^y za8CDhhKOl7MUNkn4~7&h@`AFhK3;<*6)*8h#%m4NvCL=Xl>~!!faKl&yk006r1p-X zoqtnW)wYanj};vm@A((yGP}Y@qrFVx)6ryqC&FaE3p2Pye-YhA9he{8fdH-$r+($!^T~O$u@aq4s?;E=8*NC72iu_$@vd>lg{)Ce=0( z8;~Z<0O1GGi2YcHAqd?jUn5b`NK|RakcLSDRT2zW(MwLn1ZMbrY&Ti>9!qW!R2ykl z3Rx&O*-WvpAZEH@Z7RG)+ssz^UhNp+u4&sR*KiS}Q1Z?72G#{Gy@sQ>4&mQulX2lE z;{O|Gc!HY1cpoVWY`k+GTNf}!zfB9cQKFROPotLF1U$$nVzQPNB6=uqFCOSsZ~SS+ zZz^Dp5aq793SW&cH&I0s31}E?bc9}~sCGvHRtTI}#Kkf`E!I;eIA2Ae1Oy?>`!dh4 WK!1fOUeI}tH*`}edW#i&K+9jX=D2YH diff --git a/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/out/production/main/.idea/.gitignore b/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/out/production/main/.idea/.gitignore deleted file mode 100644 index 13566b8..0000000 --- a/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/out/production/main/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/out/production/main/.idea/misc.xml b/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/out/production/main/.idea/misc.xml deleted file mode 100644 index 20f033c..0000000 --- a/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/out/production/main/.idea/misc.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/out/production/main/.idea/modules.xml b/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/out/production/main/.idea/modules.xml deleted file mode 100644 index 122a905..0000000 --- a/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/out/production/main/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/out/production/main/.idea/vcs.xml b/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/out/production/main/.idea/vcs.xml deleted file mode 100644 index 4fce1d8..0000000 --- a/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/out/production/main/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/out/production/main/main.iml b/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/out/production/main/main.iml deleted file mode 100644 index b107a2d..0000000 --- a/RemoteMonitor Desktop/out/production/RemoteMonitor Desktop/out/production/main/main.iml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/RemoteMonitor Desktop/src/main/java/com/company/Main.java b/RemoteMonitor Desktop/src/main/java/com/company/Main.java index d2640cb..5c7248a 100644 --- a/RemoteMonitor Desktop/src/main/java/com/company/Main.java +++ b/RemoteMonitor Desktop/src/main/java/com/company/Main.java @@ -1,51 +1,51 @@ package com.company; import components.ComponentManager; -import networking.Server; +import networking.MultiUserServer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; public class Main { + private static final Logger logger = LoggerFactory.getLogger(Main.class); + public static void main(String[] args) throws Exception { clearTerminal(); ConfigurationManager configurationManager = new ConfigurationManager(); ComponentManager componentManager = new ComponentManager(); - while(true) - { - Server server = new Server(configurationManager.getLocalIp(), configurationManager.getPort(), configurationManager.getKeyword()); - componentManager.updateAll(); - System.out.println("Connection Information"); - System.out.println("Local connection IP: " + configurationManager.getLocalIp() + " Port: " + configurationManager.getPort()); - System.out.println("Keyword: " + configurationManager.getKeyword()); + + System.out.println("=== Remote Monitor Multi-User Server ==="); + System.out.println("Connection Information:"); + System.out.println("Local IP: " + configurationManager.getLocalIp()); + System.out.println("Port: " + configurationManager.getPort()); + System.out.println("Keyword: " + configurationManager.getKeyword()); + System.out.println("========================================"); + + // Create and start the multi-user server + MultiUserServer server = new MultiUserServer( + configurationManager.getLocalIp(), + configurationManager.getPort(), + configurationManager.getKeyword(), + componentManager + ); + + // Add shutdown hook to gracefully stop the server + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + System.out.println("\nShutting down server..."); + server.stop(); + })); + + try { + // Start the server (this will run indefinitely) server.start(); - System.out.println(server.getConnectedIp() + " successfully connected\n"); - - while (server.isConnected()) { - String read = server.read(); - - if (read != null && read.equals("data request")) { - System.out.println("Client requested data"); - componentManager.updateAll(); - if (server.write(componentManager.toJson())) { - System.out.println("Successfully sent data to the client"); - } else { - System.out.println("Failed to send data to the client"); - - } - } - - } - System.out.println("Connection disconnected"); - System.out.println("Restarting server..."+"\n"); - server.closeServer(); - - + } catch (Exception e) { + System.err.println("Server error: " + e.getMessage()); + logger.error("Server error", e); + } finally { + server.stop(); } - - } public static void clearTerminal() throws IOException { if (System.getProperty("os.name").contains("Windows")) diff --git a/RemoteMonitor Desktop/src/main/java/components/ComponentManager.java b/RemoteMonitor Desktop/src/main/java/components/ComponentManager.java index 08c5277..fe9c69a 100644 --- a/RemoteMonitor Desktop/src/main/java/components/ComponentManager.java +++ b/RemoteMonitor Desktop/src/main/java/components/ComponentManager.java @@ -26,19 +26,52 @@ public ComponentManager() ram = new Ram(); gpus = new ArrayList(); disks = new ArrayList(); - List gpuJ = JSensors.get.components().gpus; - List graphicsCards = new SystemInfo().getHardware().getGraphicsCards(); - List hwDiskStoreList = new SystemInfo().getHardware().getDiskStores(); - List diskJ = JSensors.get.components().disks; - for (int i = 0; i < gpuJ.size(); i++) - { - gpus.add(new GPU(graphicsCards.get(i), gpuJ.get(i))); + + try { + List gpuJ = JSensors.get.components().gpus; + List graphicsCards = new SystemInfo().getHardware().getGraphicsCards(); + List hwDiskStoreList = new SystemInfo().getHardware().getDiskStores(); + List diskJ = JSensors.get.components().disks; + + // Initialize GPUs - match OSHI and JSensors data safely + int gpuCount = Math.min(gpuJ != null ? gpuJ.size() : 0, + graphicsCards != null ? graphicsCards.size() : 0); + for (int i = 0; i < gpuCount; i++) { + try { + gpus.add(new GPU(graphicsCards.get(i), gpuJ.get(i))); + } catch (Exception e) { + System.err.println("Error initializing GPU " + i + ": " + e.getMessage()); + } + } + + // Initialize Disks - match OSHI and JSensors data safely + int diskCount = Math.min(diskJ != null ? diskJ.size() : 0, + hwDiskStoreList != null ? hwDiskStoreList.size() : 0); + for (int i = 0; i < diskCount; i++) { + try { + disks.add(new PhysicalDisk(hwDiskStoreList.get(i), diskJ.get(i))); + } catch (Exception e) { + System.err.println("Error initializing Disk " + i + ": " + e.getMessage()); + } + } + + // If no JSensors disks but OSHI disks exist, create them without JSensors data + if ((diskJ == null || diskJ.isEmpty()) && hwDiskStoreList != null && !hwDiskStoreList.isEmpty()) { + for (HWDiskStore hwDisk : hwDiskStoreList) { + try { + disks.add(new PhysicalDisk(hwDisk, null)); + } catch (Exception e) { + System.err.println("Error initializing Disk (OSHI only): " + e.getMessage()); + } + } + } + + System.out.println("ComponentManager initialized: " + gpus.size() + " GPUs, " + disks.size() + " Disks"); + + } catch (Exception e) { + System.err.println("Error initializing ComponentManager: " + e.getMessage()); + e.printStackTrace(); } - for (int i = 0; i < hwDiskStoreList.size(); i++) - { - disks.add(new PhysicalDisk(hwDiskStoreList.get(i), diskJ.get(i))); - } - } public void updateAll() diff --git a/RemoteMonitor Desktop/src/main/java/components/GPU.java b/RemoteMonitor Desktop/src/main/java/components/GPU.java index 2319851..43246e7 100644 --- a/RemoteMonitor Desktop/src/main/java/components/GPU.java +++ b/RemoteMonitor Desktop/src/main/java/components/GPU.java @@ -24,10 +24,27 @@ public GPU(GraphicsCard gpu, Gpu gpu2) public void update() { try { - temperature = jgpu.sensors.temperatures.get(0).value; + if (jgpu != null && jgpu.sensors != null && jgpu.sensors.temperatures != null && !jgpu.sensors.temperatures.isEmpty()) { + temperature = jgpu.sensors.temperatures.get(0).value; + } else { + temperature = 0; // No temperature data available + } } - catch (Exception e){} - usage = jgpu.sensors.loads.get(0).value; + catch (Exception e){ + temperature = 0; // Fallback if temperature reading fails + } + + try { + if (jgpu != null && jgpu.sensors != null && jgpu.sensors.loads != null && !jgpu.sensors.loads.isEmpty()) { + usage = jgpu.sensors.loads.get(0).value; + } else { + usage = 0; // No usage data available + } + } + catch (Exception e){ + usage = 0; // Fallback if usage reading fails + } + lastUpdated = System.currentTimeMillis(); } diff --git a/RemoteMonitor Desktop/src/main/java/components/PhysicalDisk.java b/RemoteMonitor Desktop/src/main/java/components/PhysicalDisk.java index 796196d..35739af 100644 --- a/RemoteMonitor Desktop/src/main/java/components/PhysicalDisk.java +++ b/RemoteMonitor Desktop/src/main/java/components/PhysicalDisk.java @@ -20,14 +20,21 @@ public PhysicalDisk(HWDiskStore hwDiskStore, Disk Jdisk) componentName = diskStore.getModel(); componentType = "Disk"; partitions = diskStore.getPartitions(); - jdisk = Jdisk; + jdisk = Jdisk; // This can be null if JSensors doesn't detect the disk } public void update() { partitions = diskStore.getPartitions(); setAvailableCapacity(); - temperature = checkTemp(jdisk.sensors.loads); + + // Only try to get temperature if JSensors data is available + if (jdisk != null && jdisk.sensors != null && jdisk.sensors.loads != null) { + temperature = checkTemp(jdisk.sensors.loads); + } else { + temperature = 0; // No temperature data available + } + lastUpdated = System.currentTimeMillis(); } public long getAvailableCapacity() { diff --git a/RemoteMonitor Desktop/src/main/java/networking/ClientHandler.java b/RemoteMonitor Desktop/src/main/java/networking/ClientHandler.java new file mode 100644 index 0000000..5b6520c --- /dev/null +++ b/RemoteMonitor Desktop/src/main/java/networking/ClientHandler.java @@ -0,0 +1,157 @@ +package networking; + +import components.ComponentManager; +import java.io.*; +import java.net.*; +import java.util.concurrent.atomic.AtomicBoolean; + +public class ClientHandler implements Runnable { + private Socket clientSocket; + private PrintWriter writer; + private BufferedReader reader; + private String keyword; + private String clientId; + private String connectedIp; + private AtomicBoolean isAuthenticated; + private AtomicBoolean isConnected; + private ComponentManager componentManager; + private MultiUserServer server; + + public ClientHandler(Socket clientSocket, String keyword, ComponentManager componentManager, MultiUserServer server) { + this.clientSocket = clientSocket; + this.keyword = keyword; + this.componentManager = componentManager; + this.server = server; + this.connectedIp = clientSocket.getRemoteSocketAddress().toString(); + this.clientId = generateClientId(); + this.isAuthenticated = new AtomicBoolean(false); + this.isConnected = new AtomicBoolean(true); + } + + @Override + public void run() { + try { + writer = new PrintWriter(clientSocket.getOutputStream(), true); + reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); + + System.out.println("New client connection from: " + connectedIp + " (ID: " + clientId + ")"); + + if (!authenticate()) { + System.out.println("Authentication failed for client: " + connectedIp); + writer.println("failed"); + closeConnection(); + return; + } + + System.out.println("Client authenticated successfully: " + connectedIp + " (ID: " + clientId + ")"); + writer.println("connected"); + + // Wait for confirmation + String response = reader.readLine(); + if (!"received".equals(response)) { + closeConnection(); + return; + } + + // Handle client requests + handleClientRequests(); + + } catch (IOException e) { + System.out.println("Client connection error for " + connectedIp + ": " + e.getMessage()); + } finally { + closeConnection(); + } + } + + private boolean authenticate() throws IOException { + try { + String receivedKeyword = reader.readLine(); + if (receivedKeyword != null && receivedKeyword.equals(keyword)) { + isAuthenticated.set(true); + return true; + } else { + System.out.println(connectedIp + " tried connecting with wrong keyword: \"" + receivedKeyword + "\""); + return false; + } + } catch (Exception e) { + System.out.println("Authentication error for " + connectedIp + ": " + e.getMessage()); + return false; + } + } + + private void handleClientRequests() { + try { + String request; + while (isConnected.get() && (request = reader.readLine()) != null) { + System.out.println("Client " + clientId + " requested: " + request); + + if ("data request".equals(request)) { + handleDataRequest(); + } else if ("disconnected".equals(request)) { + System.out.println("Client " + clientId + " requested disconnection"); + break; + } else { + System.out.println("Unknown request from client " + clientId + ": " + request); + } + } + } catch (IOException e) { + System.out.println("Error handling requests for client " + clientId + ": " + e.getMessage()); + } + } + + private void handleDataRequest() throws IOException { + try { + // Update component data + componentManager.updateAll(); + String jsonData = componentManager.toJson(); + + writer.println(jsonData); + + // Wait for confirmation + String response = reader.readLine(); + if ("received".equals(response)) { + System.out.println("Successfully sent data to client " + clientId); + } else { + System.out.println("Failed to confirm data delivery to client " + clientId); + } + } catch (Exception e) { + System.out.println("Error sending data to client " + clientId + ": " + e.getMessage()); + isConnected.set(false); + } + } + + private void closeConnection() { + isConnected.set(false); + try { + if (reader != null) reader.close(); + if (writer != null) writer.close(); + if (clientSocket != null && !clientSocket.isClosed()) { + clientSocket.close(); + } + server.removeClient(clientId); + System.out.println("Client disconnected: " + connectedIp + " (ID: " + clientId + ")"); + } catch (IOException e) { + System.out.println("Error closing connection for client " + clientId + ": " + e.getMessage()); + } + } + + private String generateClientId() { + return "CLIENT_" + System.currentTimeMillis() + "_" + Math.random(); + } + + public String getClientId() { + return clientId; + } + + public String getConnectedIp() { + return connectedIp; + } + + public boolean isConnected() { + return isConnected.get(); + } + + public boolean isAuthenticated() { + return isAuthenticated.get(); + } +} \ No newline at end of file diff --git a/RemoteMonitor Desktop/src/main/java/networking/MultiUserServer.java b/RemoteMonitor Desktop/src/main/java/networking/MultiUserServer.java new file mode 100644 index 0000000..83701ef --- /dev/null +++ b/RemoteMonitor Desktop/src/main/java/networking/MultiUserServer.java @@ -0,0 +1,145 @@ +package networking; + +import components.ComponentManager; +import java.io.IOException; +import java.net.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.Map; + +public class MultiUserServer { + private int listeningPort; + private String keyword; + private ServerSocket serverSocket; + private AtomicBoolean isRunning; + private ExecutorService threadPool; + private ComponentManager componentManager; + private Map connectedClients; + private String localIp; + + public MultiUserServer(String ip, int port, String connectionKeyword, ComponentManager componentManager) throws IOException { + this.localIp = ip; + this.listeningPort = port; + this.keyword = connectionKeyword; + this.componentManager = componentManager; + this.isRunning = new AtomicBoolean(false); + this.threadPool = Executors.newCachedThreadPool(); + this.connectedClients = new ConcurrentHashMap<>(); + this.serverSocket = new ServerSocket(listeningPort, 0, InetAddress.getByName(ip)); + } + + public void start() { + if (isRunning.get()) { + System.out.println("Server is already running!"); + return; + } + + isRunning.set(true); + System.out.println("Multi-user server started on " + localIp + ":" + listeningPort); + System.out.println("Keyword: " + keyword); + System.out.println("Waiting for client connections..."); + + while (isRunning.get()) { + try { + Socket clientSocket = serverSocket.accept(); + + if (!isRunning.get()) { + clientSocket.close(); + break; + } + + // Create a new client handler for each connection + ClientHandler clientHandler = new ClientHandler(clientSocket, keyword, componentManager, this); + connectedClients.put(clientHandler.getClientId(), clientHandler); + + // Execute client handler in a separate thread + threadPool.execute(clientHandler); + + System.out.println("Total connected clients: " + connectedClients.size()); + + } catch (IOException e) { + if (isRunning.get()) { + System.err.println("Error accepting client connection: " + e.getMessage()); + } + } + } + } + + public void stop() { + if (!isRunning.get()) { + return; + } + + isRunning.set(false); + System.out.println("Stopping multi-user server..."); + + // Close all client connections + for (ClientHandler client : connectedClients.values()) { + // ClientHandler.closeConnection() will be called automatically + } + connectedClients.clear(); + + // Shutdown thread pool + threadPool.shutdown(); + try { + if (!threadPool.awaitTermination(5, TimeUnit.SECONDS)) { + threadPool.shutdownNow(); + } + } catch (InterruptedException e) { + threadPool.shutdownNow(); + Thread.currentThread().interrupt(); + } + + // Close server socket + try { + if (serverSocket != null && !serverSocket.isClosed()) { + serverSocket.close(); + } + } catch (IOException e) { + System.err.println("Error closing server socket: " + e.getMessage()); + } + + System.out.println("Multi-user server stopped."); + } + + public void removeClient(String clientId) { + connectedClients.remove(clientId); + System.out.println("Client removed. Total connected clients: " + connectedClients.size()); + } + + public int getConnectedClientCount() { + return connectedClients.size(); + } + + public boolean isRunning() { + return isRunning.get(); + } + + public String getLocalIp() { + return localIp; + } + + public int getPort() { + return listeningPort; + } + + public String getKeyword() { + return keyword; + } + + public Map getConnectedClients() { + return new ConcurrentHashMap<>(connectedClients); + } + + // Method to broadcast data to all connected clients (if needed in future) + public void broadcastToAllClients(String data) { + for (ClientHandler client : connectedClients.values()) { + try { + // This would require adding a broadcast method to ClientHandler + // For now, we'll keep the individual request-response model + } catch (Exception e) { + System.err.println("Error broadcasting to client " + client.getClientId() + ": " + e.getMessage()); + } + } + } +} \ No newline at end of file From c244ece7b83a17fc96531622586d7b118c7eb321 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 22 Sep 2025 12:50:13 +0000 Subject: [PATCH 3/4] Revamp mobile UI to support multiple components and improve user experience Co-authored-by: km <39051822+km@users.noreply.github.com> --- .../RemoteMonitor/Components/CPU.cs | 12 + .../RemoteMonitor/Components/Ram.cs | 9 + .../RemoteMonitor/Connection.xaml | 130 ++++- .../RemoteMonitor/Connection.xaml.cs | 54 +- .../RemoteMonitor/RemoteMonitor/Monitor.xaml | 173 +++++-- .../RemoteMonitor/Monitor.xaml.cs | 483 ++++++++++++++---- 6 files changed, 680 insertions(+), 181 deletions(-) diff --git a/RemoteMonitor Mobile/RemoteMonitor/RemoteMonitor/RemoteMonitor/Components/CPU.cs b/RemoteMonitor Mobile/RemoteMonitor/RemoteMonitor/RemoteMonitor/Components/CPU.cs index 32ea9e0..615336f 100644 --- a/RemoteMonitor Mobile/RemoteMonitor/RemoteMonitor/RemoteMonitor/Components/CPU.cs +++ b/RemoteMonitor Mobile/RemoteMonitor/RemoteMonitor/RemoteMonitor/Components/CPU.cs @@ -19,6 +19,18 @@ public CPU(string name, double temp, double componentUsage, int coreAmount, long componentType = "CPU"; update(temp, componentUsage, coreAmount, maxSpeed, currentSpeeds, fanSpeeds); } + public CPU() + { + componentName = "CPU"; + componentType = "CPU"; + temperature = 0; + usage = 0; + cores = 0; + speed = 0; + currentSpeed = new long[0]; + fanSpeed = new int[0]; + } + public CPU(JObject json) { componentName = json["componentName"].ToString(); diff --git a/RemoteMonitor Mobile/RemoteMonitor/RemoteMonitor/RemoteMonitor/Components/Ram.cs b/RemoteMonitor Mobile/RemoteMonitor/RemoteMonitor/RemoteMonitor/Components/Ram.cs index 4262337..9dccb38 100644 --- a/RemoteMonitor Mobile/RemoteMonitor/RemoteMonitor/RemoteMonitor/Components/Ram.cs +++ b/RemoteMonitor Mobile/RemoteMonitor/RemoteMonitor/RemoteMonitor/Components/Ram.cs @@ -11,6 +11,15 @@ public class Ram : Component public long memoryTotal; public long memoryAvailable; + public Ram() + { + componentType = "Ram"; + componentName = "RAM"; + memoryTotal = 0; + memoryAvailable = 0; + usage = 0; + } + public Ram(string name, long ramTotal, long availableRam) { componentType = "Ram"; diff --git a/RemoteMonitor Mobile/RemoteMonitor/RemoteMonitor/RemoteMonitor/Connection.xaml b/RemoteMonitor Mobile/RemoteMonitor/RemoteMonitor/RemoteMonitor/Connection.xaml index 141d592..817129c 100644 --- a/RemoteMonitor Mobile/RemoteMonitor/RemoteMonitor/RemoteMonitor/Connection.xaml +++ b/RemoteMonitor Mobile/RemoteMonitor/RemoteMonitor/RemoteMonitor/Connection.xaml @@ -2,19 +2,121 @@ - - -