From 048a9d663623b18a09aa2da5072946ed2aa88dc7 Mon Sep 17 00:00:00 2001 From: Kenneth <2448698686@qq.com> Date: Wed, 20 Nov 2024 08:57:20 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BE=A6=E5=AF=9F=E8=80=85?= =?UTF-8?q?=E5=92=8C=E6=8C=87=E6=8C=A5=E8=80=85=E4=B9=8B=E9=97=B4=E7=9A=84?= =?UTF-8?q?=E9=80=9A=E8=AE=AF=EF=BC=8C=E6=8C=87=E6=8C=A5=E8=80=85=E5=8F=AF?= =?UTF-8?q?=E4=BB=A5=E6=8E=A5=E5=8F=97=E5=92=8C=E6=89=93=E5=9B=9E=E4=BE=A6?= =?UTF-8?q?=E5=AF=9F=E8=80=85=E5=8F=91=E9=80=81=E7=9A=84=E6=B6=88=E6=81=AF?= =?UTF-8?q?=EF=BC=8C=E4=BE=A6=E5=AF=9F=E8=80=85=E8=83=BD=E7=9C=8B=E5=88=B0?= =?UTF-8?q?=E6=8C=87=E6=8C=A5=E8=80=85=E7=9A=84=E5=91=BD=E4=BB=A4=EF=BC=8C?= =?UTF-8?q?=E7=9B=B8=E5=BD=93=E4=BA=8E=E5=A2=9E=E5=8A=A0=E5=8F=82=E8=B0=8B?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E3=80=82=E5=90=8C=E6=97=B6=E9=83=BD=E8=83=BD?= =?UTF-8?q?=E6=B8=85=E7=A9=BA=E8=BF=87=E5=A4=9A=E7=9A=84=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E4=BD=BF=E7=BD=91=E9=A1=B5=E4=B8=8D=E6=98=BE=E5=BE=97=E6=8B=A5?= =?UTF-8?q?=E6=8C=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TheBattleCar/10测试文档.xlsx | Bin 0 -> 11515 bytes TheBattleCar/app.log | 3534 ++++++++++++++++++++++ TheBattleCar/app.py | 196 +- TheBattleCar/createkey.py | 20 + TheBattleCar/secret.key | 1 + TheBattleCar/server.js | 29 + TheBattleCar/static/login.css | 211 ++ TheBattleCar/templates/attacker.html | 15 +- TheBattleCar/templates/commander.html | 178 +- TheBattleCar/templates/login.html | 84 +- TheBattleCar/templates/network.html | 39 + TheBattleCar/templates/register.html | 33 + TheBattleCar/templates/scout.html | 79 +- TheBattleCar/templates/send_message.html | 15 +- 14 files changed, 4355 insertions(+), 79 deletions(-) create mode 100644 TheBattleCar/10测试文档.xlsx create mode 100644 TheBattleCar/createkey.py create mode 100644 TheBattleCar/secret.key create mode 100644 TheBattleCar/server.js create mode 100644 TheBattleCar/static/login.css create mode 100644 TheBattleCar/templates/network.html create mode 100644 TheBattleCar/templates/register.html diff --git a/TheBattleCar/10测试文档.xlsx b/TheBattleCar/10测试文档.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..374a613c09d60fb8e756b689f5a2e9cb95ca9536 GIT binary patch literal 11515 zcmeHNWm{b7vW3Ro-8HzoTL|vbxVr^+cPChayF&=>?iw6|O9&F&y)QF!&YhXuxxe6? z{bBd+-g{L){dUz_^;VUVECeJb7&I6x7#J8CSP9}!PfKtxFeE52FbptQfR4C>y^EQ> zi-DTwdoyP}CJ#GX(tJn&O)ePV_4)rE|G_IznLK9S%Yyp$Hst~3LzBAkettO}AX+Gu zQRM)p`6dK-NA*=?>+~mXX*nGf*;2oZfb-Xhe(r*i<#b~xv<7!h0u2a_fFyk@?&@zt zM@8)xP>Jtla8Gm12}HQ?3=Cq;Gr)j__Tij1k-ZRmG&)}Z^d#LyS%dHBY1RgLQN)<~ z3Ga>#-wzeJL&nJ*ax8gVLB;~{>9Q9O&KIO1gDX8&vE3@uBT-{ggA!FcoeoioR?*7m z(rmuWgF7T54SK_^O@adSHgxdi=isBtBChCcYkL;M{O_CZuKbjVun!y$G9+b{^qK6^ zMMBAfl$HPqoa*}Y^z|!`Lfu~nhA-LLzkE1(u02B|N$%u6^AX$-OXUSfEaP^|#tTLh zQ#6qWd6j%hbaaI1YCyS{+B3)Z?M}{xEm1Tg`S7_7Q5u%q>JCnN!|0K$_$o`#ZU3T5 zBx^KPmeS$tpo5v$rT}PsaO2gtKp+S(rN0FzhJL3R;59%uUgHnpH9!rV%xs;RnSML} zH!%N$qwz04y)sc=7J?Nu>@)~OHr~O%LPtJh%lvj<-t-xqHSO7uJ1wEG_4!s()FrQx z*ekQzJ=-(w+Pt>FqX5<04L$WOTu`R@Y@0@}>~nK73|f+tWbBbtZy>pC`Ok`L_E@^z zyrpZQsLJj95GE>60Iushje#J+7F{bIV2Ts2_LU4uIhAh8E>YM9zS0E8z@!u`zcWO> z&|Uj|I~TWnwbhuH!$=VYeL}IsWP;XR!Z)$QOU`_ayduh;FMgv35u=afCJ@ALw4ZbK zPi>}ER3xcF(;>2c+#m5k)wdVEb;j^tO_TK5V`*nYDFNCukL2I7)(DzRYJTNLpIonf z_{Wejwt+N9ga8A}h5-XZd40memf79G$;Q~h!R9wTD^$00$Y4Qz5wZe--}6IZNCD`| zQc>%r?64ZF9;sBm2Vt}W%m+Et)IpDv2_MbNiYwnnPTa?Z@0}25Tt@TBHdxTf3_6o+ zv13?q#Cwciq{N??=dHifrj;g6O5U4$$6POg6MVWcxu`23==4$uE~5WH^P%<(u^S>f})dPKMbdd^{swYcv5zcxVGAEeQx>b-W2P1aeCm z$|+_HjbxpA20kbzitRGGs|X7y5rNv|k&n=rR$AZXHF$Bpvxe5&99cF57~s4th4d_U z!s))N9tBc*jC{O6%#BUGQhr(DU=gAb_0 z04hYv)yotL;d@^WtR;SxZ}wwt-JbVJog(|dRzyMmbN$XtpK){oR^OlF+B$x{q$Ca ztAIGlo_1})31Dk@2;5~gc$6BFX=D!n(dsDl1xTGsTH+uo)pnCqs}6{99O6t_4K4a~ zzaOAHH3PpjGylGO*yCLpFI}KEyNxHssgA3UF;CL`Dkk3dqcZmh>6i>^dy;4=eEHDg zV(O`Z;@xss?XfWxF81LV@Q%D$l60cQnPb%O)>u7N66ChV6G)?>gDpc2H?esV*E#P7 zF!3Ik-Hn zo#}d6xZb?kjKsag+$82UBI1U9b}PoV!d1b-{}?!dLdhR5U+=WOY7IUZEck2S{2@1g z4WEBY5BO_N_^M0)*+->{ylg)UY6rqgIE#CR8y4C(7iRJ!^`9uPBlWZ^)MV^_R~rO$ zt$M%(S!M`_FwfJ8A-7vjmK^jD0E0K4BJzFD2Iv52?$u@<0|5ycTgDUM~6Qv zjuDX4oiSR35{DVGF?oL6(NN)q7Zj6AT(!)Eaad2XxUyM0PZ5pEYpsvfe-C&FQ9Y^( zs&8r{O{X>A1+|E;+(739d6GkX6!ZymAq^jXN8(SL=)9Ys)~0^CX#Stm6YJg5@t0Sw zrAGt5$K@-AhM&}-CY|FtlV%$*DgRGIcTdkNA#iSb> z+3(oVwT99YrPoA66%0pqE_T8PL^GK2Oj#v_lUZ0h^{arHf*Xk(npL zmKVV2gQcX?2hWq~sPSjeoSad_HB&af%=nb#Iui8t()yt&u-2_LP<&R8 zj%Y~e%>pD#MC~zWND?%r0&iK|Zx7z*}@+3mROLNHbif2^!v}0ql@C-xelCmZ~xR;KMXmK`$A)uUXk6M$6 zaO6zGuDeOTss}k~=AV!r_>j2XqS*0uR;iQdr$2;cZ1t3kk5ZDZgs2uUl5t_oxRU)d z62j0yuj~KvQ0QeycC|uUR!jH%=j;2Ki(oiM~0V>bJ4(Or6M+amVur$Cx=OBkrzKb42qvylVYefjsO0knDLsME| zhFT`D!VgE}l_`WjxvfLy%8z^IX6eo%P}Tv_(D%+sVoxVil8GvcqM>il7+M*p;!nEO za->3qYJXaefRcW_)uS5H|AyJn3NF>2Th>M^0l~L;9U+h2{H)W-jZaOpyZil{f8Elg z+@(;jzSbM&UI_!^56*D0G_x~f{{8$rT^wmmI1s$W?4mdquDn?{KYpNyJybi_gpgk@ zbRXtp3nE%$C{P1h)g1cs5*6l~91OnK4ymjmpu8 zE}^m^s|>I`B}RH$e~C^~Il>4b=4`6AGLSRw2#@JcW$ zBm{*~c*_4};UtBzUKLfjC9qLqanT=2PZU+5;z5o$7CU^w`dZt>p~nECRCnk)y+g9P zX0rs`QUIDWmI3?gv3b=j(-*3Q`-9E3mCqWF*q!~Lne_2zYj5UKZ4V^2CmWkP^NzKu zZ?D&P5BM)CQ*g_i(OuAZJ|;*T6^ne=*`bTMpAubK!;pil3pAOh5Qamhec!ZytGK#t zh4P6EvIK^t@)`H493a+1u35CB7+^(_ORFeOvI&Tqz^)+YoAyV#i{t~#*{6^ti%x&c z11mdJhCGeOrKxpZ!tsJ6fKI;GPi>lCbG)jvg?WANj;^-iOX7*Mgr0iNYGH4c@l)Uo z{4Nhj41B*ozg+$N7%%L;^A-;@c1r?!nzgVerJPpD$1xDNzy6klW8inO(iBg0CKxAa zc9%d2^x!^=bdRRW&ESe*RU{YvGS=_9DXut{c8KhZo3wm7dvg@AI&;Y2cd$##M*HuSlUpQb@~WsJQvy?>w< z!$fwRB1$EaJk$7~%)vIQM!d~C1n4G6X)+0!A$3Z8z8t|L&qn#W!%3BRqy+C8*98Ps zFs=};pD)L>)}L&f5Wv9&mWtnz6{q4==jrD64>(1jYjfR!C)UUg_r%1HHD@Pm9>A*p zxE5mwiT*(i<14Gsg}mE$d?U^$YfJgj^l;lV0GFPk&2~9bIg!_l+DdoOkF*#yf0*BR z21?k}Ev(ey3_^yx^%1!zwe2etWK*6~>RWB-h=)YyaOP?w^SzxI1=Iy~=<-(eYK+8e zt@e$S<9oZtp-6Vm8_lR|>Q&Ge33ugeVx!@xYx+aIP(RJQ=cZ0EhtXaCP9|nqR<#4O zwyKQN{xxq!*dhqtf;*A@8=dZBjGL_@V)!dyGj4w^t{=8tXJ|B!_LM~aCMF!S31CoM z(Dg74tNP2#vtRaVrrfxPmeoSApQiX-*)8Iso047X@XPw@URf386>G)wjz+yI#8t-Nh#V> zvDIA5^Ii33V|L)6#Jhi>YJ_;ppt+JBp@@4lt33&*m}%H>E;f}X>&|PAYrll%yI^Yx z1o7IcyQ{))0FA?$4<}@Nx1vUOy9L_g=tnEsjMqx#)NdehO+EmiKQn@wo(&(1U@Mgi zKleIs#9J7Y%MdJiOJit!Ov#Xciz!81``%B`9+7*`wS9XzifO6ZTliyPdIqjruUVO# z+~J9SKTUrqa(Ms&k!3c6E38_>1A%+{R_l3`0qfEQi!2A#`Dy~ybgF~h^eC%K+>JOw zhrs8W9((^aY##oPZ;zK(Tfo+==gM{b*Iy0_r$8DsAcTO}6Y-RT-cimHl}}VZA%Kk{ zUFKYk2`I%(mNRR@zvlzLiUFr`A6oXS81Uh}7NP$T17{acTQle1vc^{#u;1ZA?ZnyV zhi#>QsG*b%I}QawG9>inOGmH6YZu!Z(@y8^_pci}bX+fm?^o@0T-mjXkQ9i^G$t>l zWH-fLv3@^s6C}y{vrTk}%J2GaAt9Tw)>9Fl71_&Sx4pPCE3=V+weo)SDWkjqPk6 zSEm~ZUqZb_563=KCiiFVGN5U8ub4`U8T(W^S%y(Z(JOR6duG~xtP=70Aa;rrt3~nk@ZX^uKT_c01Z?s2# zWG#rX0ek_=Q=-R{aTGnjk2e54Tyno{5EFob#UkMUtg8w}N2?0hN{%j`E1W7x#2jTV zS)!()a?yN$+^##R%HUOFX=a67j4p%n*}d?ik3R{tc}Hq(^4buFMOzEfVN!8fpS_-%C&~)fj5Z z^ztbUNp~i$suzXLVEhQg`ijIDmsN69Q*-;;7vQUE?2qjf z`iij>8#cFuRSxIaGNCdas?gh+J}_dwe4Q}dIQ9vyl5Dn)qh`xAKrmEm51)WR2x|^4 z4d{nG#hjOyXPi=Rv+oV}VM?O402uUxaH4MKnku6<1l-`zh4u+NDulH4G3gG|)>dez zZl|B+1Yvm=D|!_e&EQX^QC$A`Em{=>wdv*fHD71QL$@-+uL$>zq265-0Q6^zA(or7 zcOU&WL+pnf)sSd`bLWrEv|9uqP~9NsG#~0WS5&J+!;qW8CpKi}t*N>0+m zDC7=cmA7>nutuf0u;lMc+8S)%uZCgCEwg~))-q9lL27OHW(g)Gksz^cZzj&6N#%>d9bfZ6Mgrg-Bn1 z$LGg=6)bIdr_8~*Dm}z4nG|UkQul#K{+RTPx}f-uI9wK~i78HFDg+9v(nQfs=N1#( z@B6Ui60I_K#ywgle$U69PiE1oE6buZ$IIhIAVYIs5oroc1jiC?E-|OrR37qAOrNI- zXWM&Clir|Y_=&hc>|FY`67Eb_rZgLoK+`VrVtUbmPN>t@LE0 zdF{~7C69RU#fpv9P?Ok*pWwta&+8Hwb2qMx(IWPGYI%$Syi}`@u9n9d2$8V+NR-+> zd+*;Z4A(JI90D7+9%xtqT|0OmEcjJ7h{VyZtXsXm5*p|f+u?}2mbEWpP!1%UK02HD zYtLzJbq6d$Q;hpkjvvMo_xb;0Ru8@}9|U?Oa@p5P0Or4l+|tO&%v9CI$;#g1cRtV5 z)N#PqMD=U>4l+E~53Zt7XSTWAXXj##{N{UTu%DU5NhYE~>oC?b!M!o=!(J))Gb&-qhKy zwdv?{$z={EpR(y}z##_H=2{7w=VdbgmS2W7res-D8h^_?udGrfVIfivU~sN- zVFGdt=kJY{_WH>C&F?)Y@{R656;af2V_8a^H9Zx0dKB({rnRUM$b6uv&0YYf^|7M#Tn}r zIYh{dMx@r@9D|31M%%3IaMFufxHd0v-G17BMF}Jj;I%`CfC%NgTiLGlOGe#v4iQ0s zZtwwfffU#<+|6Z+I2VQR;(XHACHYx`G-8im=2R(3@k2TD179RY){jtFK9~{T zm&W+e9g%GQybjmnG0e<=L5_O7sA-t4Pte|f#+72 ztO3n+vVLYSEo46Hj1$u64DVuck7bZCjEe2|6-bkW7z*pDoj|qNJ~@FJCov-8Ku|?b zqfDafW!gktdu*0yhY-a>Ozuy7_({fm&-NwJry!V!xz^!RM|SG{2 z;NC8V+7j;2K*YQ$-lb*Y`<`*VPoQQCiW)t9t)aweHH2n2 zBKQc!taGm_2Ja*Ft|A(N&0!PSxA99_fmDey)lp`w6esK*$;-==>0Q7UiZBdchUtRNy4Zp;(~YP3x~u-FDzn&&p#r%!Zw6KzC9=$ph?7>C2CK} zQ`-(so{1#YXU(~)+b35GHa0Fxm5QfcZ#LN{$cqnWvR&RGjtj)MKuM>{n4NTSbdh0Z zGPG<+0-Hp$KI>I_qi5R{tH}O>w{-Vff%?Cl?Nt)I7pd1hf#GYn0qwQhVCrC^;vyCkkt&LID&jgN}V&#F7xu65f19?EYUO-696w?e|%C@`{&L@#q^0v?5q1dzq%jlU)|5>{rmrV->cjG z>&Q%$SLl1K-QP;Bl3ir;L4_#o;*$CG10;&DZwAvius;)h6Q6U!=3+=_2B)`&Kp!$p zj7S8~yRlzNe$B~YM8`BH{3fAlM*o>aak(+se*^}+Xt097ELL;PmTtdl6^Ic?#}Orn`T|&`v5(= z2@dM?;tRZS)=$+|C$4=s)g@z50YyBObT;*3twrrDe0Tc@athe^m7BiGsB4f{dMwS! zWt-0$a`mcX$Xdw*e2S7#Ro zyZ?IezkL`CtnkCvKR7f9Bt9%S5#Ol8zZ}P5H!!Zo2E({QfKpf^J+xUi7r6|TN`9ZRFm9xtXn4y(0k&ZQA+`7qd{ zxPE8|in3LAu4P{t+WGEM_Z`6xa?SFQE7ZYkc#Msb%sAr{g^XpOv9LZlI$AIMUyZjwRqwbS=FmunzWo&^hS;?Kb~=vgcRu-{%?r zguYf9;eQAJKhq7r+WED~{ih|7*Uj$#*Yf_=%CBv&Kdrc+{%+;hCfKhAel3;$X&?~$ zcLRSGPJe~|x;g(7Dns}O^w+KWuNMBEt^J7y1M?;a1N%R@+pqAytL 0: + return '用户已经存在 返回登录' + else: + code = "INSERT INTO users(username, password, role) VALUES('%s', '%s', '%s')" % (username, password, role) + print(con_my_sql(code)) + return '注册成功 返回登录' + else: + print(form.errors) + return redirect(url_for('register')) + # 侦查者页面 @app.route('/scout') @login_required @@ -156,8 +217,75 @@ def scout(): logger.info("Accessing scout page") if current_user.role != '侦查者': logger.warning("Unauthorized access to scout page") + return '用户无此页面访问权限 返回登录' + + # 获取侦察者的通知 + cursor = mysql.connection.cursor() + cursor.execute("SELECT * FROM notifications WHERE user_id = %s ORDER BY created_at DESC", (current_user.id,)) + notifications = cursor.fetchall() + cursor.close() + logger.info(f"Notifications fetched: {notifications}") + + return render_template('scout.html', notifications=notifications) + +# 处理消息 +@app.route('/handle_message//', methods=['POST']) +@login_required +def handle_message(message_id, action): + logger.info(f"Handling message action: {action} for ID: {message_id}") + if current_user.role != '指挥者': + logger.warning("Unauthorized access to handle message") return redirect(url_for('login')) - return render_template('scout.html') + + cursor = mysql.connection.cursor() + if action == 'accept': + cursor.execute("UPDATE messages SET status = 'accepted' WHERE id = %s", (message_id,)) + flash('消息已接受') + elif action == 'reject': + cursor.execute("UPDATE messages SET status = 'rejected' WHERE id = %s", (message_id,)) + flash('消息已打回') + mysql.connection.commit() + cursor.close() + logger.info(f"Message status updated: {action}") + + # 获取消息内容 + cursor = mysql.connection.cursor() + cursor.execute("SELECT message FROM messages WHERE id = %s", (message_id,)) + message_data = cursor.fetchone() + cursor.close() + logger.info(f"Message data fetched: {message_data}") + + # 将结果反馈给侦察者 + cursor = mysql.connection.cursor() + cursor.execute("SELECT id FROM users WHERE role = '侦查者'") + scouts = cursor.fetchall() + cursor.close() + logger.info(f"Scouts found: {scouts}") + + for scout in scouts: + cursor = mysql.connection.cursor() + cursor.execute("INSERT INTO notifications (user_id, message_id, action, message) VALUES (%s, %s, %s, %s)", + (scout['id'], message_id, action, message_data['message'])) + mysql.connection.commit() + cursor.close() + logger.info(f"Notification inserted for scout: {scout['id']}") + + return redirect(url_for('commander')) + +# 清除通知 +@app.route('/clear_notifications', methods=['POST']) +@login_required +def clear_notifications(): + user_id = request.json.get('user_id') + if not user_id: + return jsonify({'success': False, 'message': 'User ID is required'}), 400 + + cursor = mysql.connection.cursor() + cursor.execute("DELETE FROM notifications WHERE user_id = %s", (user_id,)) + mysql.connection.commit() + cursor.close() + + return jsonify({'success': True, 'message': 'Notifications cleared successfully'}) # 指挥者页面 @app.route('/commander') @@ -166,7 +294,7 @@ def commander(): logger.info("Accessing commander page") if current_user.role != '指挥者': logger.warning("Unauthorized access to commander page") - return redirect(url_for('login')) + return '用户无此页面访问权限 返回登录' # 获取特定目录下的所有文件和攻击坐标状态 directory = 'E:/_Ufo/0000jiegou/TheBattleCar/uploads' @@ -185,7 +313,13 @@ def commander(): attacks = cursor.fetchall() cursor.close() - return render_template('commander.html', media_items=media_items, attacks=attacks) + # 获取侦察者发送的消息 + cursor = mysql.connection.cursor() + cursor.execute("SELECT id, message, photo_url, created_at, status FROM messages ORDER BY created_at DESC") + messages = cursor.fetchall() + cursor.close() + + return render_template('commander.html', media_items=media_items, attacks=attacks, messages=messages) # 指挥者发送攻击坐标 @app.route('/send_attack', methods=['POST']) @@ -210,6 +344,47 @@ def send_attack(): flash('攻击坐标已发送') return redirect(url_for('commander')) + +# 清除照片 +@app.route('/clear_photos', methods=['POST']) +@login_required +def clear_photos(): + logger.info("Handling clear photos request") + if current_user.role != '指挥者': + logger.warning("Unauthorized access to clear photos") + return redirect(url_for('login')) + + directory = app.config['UPLOAD_FOLDER'] + for filename in os.listdir(directory): + file_path = os.path.join(directory, filename) + try: + if os.path.isfile(file_path): + os.unlink(file_path) + except Exception as e: + logger.error(f"Error deleting file: {str(e)}") + flash(f"Error deleting file: {str(e)}") + + logger.info("Photos cleared successfully") + flash('照片已清空') + return redirect(url_for('commander')) + +# 清除侦察者发送的消息 +@app.route('/clear_messages', methods=['POST']) +@login_required +def clear_messages(): + logger.info("Handling clear messages request") + if current_user.role != '指挥者': + logger.warning("Unauthorized access to clear messages") + return redirect(url_for('login')) + + cursor = mysql.connection.cursor() + cursor.execute("DELETE FROM messages") + mysql.connection.commit() + cursor.close() + + logger.info("Messages cleared successfully") + flash('消息已清空') + return redirect(url_for('commander')) # 攻击者页面 @app.route('/attacker') @@ -218,7 +393,7 @@ def attacker(): logger.info("Accessing attacker page") if current_user.role != '攻击者': logger.warning("Unauthorized access to attacker page") - return redirect(url_for('login')) + return '用户无此页面访问权限 返回登录' # 获取攻击坐标列表 cursor = mysql.connection.cursor() @@ -281,7 +456,7 @@ def send_message(): # 插入数据到 MySQL cursor = mysql.connection.cursor() - cursor.execute("INSERT INTO messages (message, photo_url) VALUES (%s, %s)", (message, photo_url)) + cursor.execute("INSERT INTO messages (message, photo_url, status) VALUES (%s, %s, %s)", (message, photo_url, 'pending')) mysql.connection.commit() cursor.close() logger.info(f"Message sent: {message}, Photo URL: {photo_url}") @@ -296,7 +471,7 @@ def send_message(): def get_messages(): logger.info("Handling get messages request") cursor = mysql.connection.cursor() - cursor.execute("SELECT id, message, photo_url, created_at FROM messages") + cursor.execute("SELECT id, message, photo_url, created_at, status FROM messages") result = cursor.fetchall() cursor.close() @@ -306,7 +481,8 @@ def get_messages(): 'id': row['id'], 'message': row['message'], 'photo_url': row['photo_url'], - 'created_at': row['created_at'] + 'created_at': row['created_at'], + 'status': row['status'] }) return jsonify(messages) diff --git a/TheBattleCar/createkey.py b/TheBattleCar/createkey.py new file mode 100644 index 0000000..7e32437 --- /dev/null +++ b/TheBattleCar/createkey.py @@ -0,0 +1,20 @@ +from cryptography.fernet import Fernet +import os + +# 生成一个新的Fernet密钥 +key = Fernet.generate_key() + +# 指定密钥文件的路径 +key_path = 'secret.key' + +# 将密钥保存到文件中 +with open(key_path, 'wb') as key_file: + key_file.write(key) + +# 打印密钥以便查看 +# print(f"Generated key: {key.decode()}") + +# 确保密钥文件的权限设置为只读 +os.chmod(key_path, 0o400) + +print(f"Key has been saved to {key_path}") \ No newline at end of file diff --git a/TheBattleCar/secret.key b/TheBattleCar/secret.key new file mode 100644 index 0000000..aa43d09 --- /dev/null +++ b/TheBattleCar/secret.key @@ -0,0 +1 @@ +xO0rhaZ7_TEiOBm2ZH2b6L9VIiECc_aO8FeY5HGt2nY= \ No newline at end of file diff --git a/TheBattleCar/server.js b/TheBattleCar/server.js new file mode 100644 index 0000000..f0571d5 --- /dev/null +++ b/TheBattleCar/server.js @@ -0,0 +1,29 @@ +// server.js +const express = require('express'); +const http = require('http'); +const socketIo = require('socket.io'); + +const app = express(); +const server = http.createServer(app); +const io = socketIo(server); + +let clients = {}; + +io.on('connection', (socket) => { + console.log('A client connected:', socket.id); + clients[socket.id] = { status: 'connected' }; + + socket.on('disconnect', () => { + console.log('A client disconnected:', socket.id); + clients[socket.id] = { status: 'disconnected' }; + }); + + // 定时发送客户端状态 + setInterval(() => { + io.emit('clients_status', clients); + }, 5000); +}); + +server.listen(3000, () => { + console.log('Server listening on port 3000'); +}); \ No newline at end of file diff --git a/TheBattleCar/static/login.css b/TheBattleCar/static/login.css new file mode 100644 index 0000000..cea7f56 --- /dev/null +++ b/TheBattleCar/static/login.css @@ -0,0 +1,211 @@ +*{ + /*初始化 清除页面元素的内外边距*/ + padding: 0; + margin: 0; + /*盒子模型*/ + box-sizing: border-box; +} +body { + /*弹性布局 让页面元素垂直+水平居中*/ + display: flex; + justify-content: center; + align-items: center; + /*让页面始终占浏览器可视区域总高度*/ + height: 100vh; + /*背景渐变色*/ + background: linear-gradient(#141e30,#243b55); + +} +.login{ + /*弹性布局 让子元素称为弹性项目*/ + display: flex; + /*让弹性项目垂直排列 原理是改变弹性盒子的主轴方向 + 父元素就是弹性盒子 现在改变后的主轴方向是向下了*/ + flex-direction: column; + /*让弹性项目在交叉轴方向水平居中 现在主轴的方向是向下 + 交叉轴的方向是与主轴垂直 交叉轴的方向是向右*/ + align-items: center; + width: 400px; + padding: 40px; + background-color: rgba(0, 0, 0, 0.2); + box-shadow: 0 15px 25px rgba(0, 0, 0, 0.4); + +} + +.login h2{ + color: #fff; + margin-bottom: 30px; +} +.login h3{ + color: #fff; + margin-bottom: 10px; +} +.login .login_box { + /*相对定位*/ + position: relative; + width: 100%; +} +.login .login_box input{ + /*清除input框自带的边框和轮廓*/ + outline: none; + border: none; + width: 100%; + padding: 10px 0; + margin-bottom: 30px; + color: #fff; + font-size: 16px; + border-bottom: 1px solid #fff; + /*背景颜色为透明色*/ + background-color: transparent; +} + +.login .login_box label{ + position:absolute; + top: 0 ; + left: 0; + padding: 10px 0; + color: #fff; + /*这个属性的默认值是auto 默认是这个元素可以被点击 + 但是如果我们写了none 就是这个元素不能被点击,就好像它可见但是不能用 + 可望而不可及*/ + /*这个就是两者的区别*/ + pointer-events: none; + /*加个过度*/ + transition: all 0.5s; +} +/*: focus 选择器是当input获得焦点是触发的样式 + 是相邻兄弟选择器 + 去找与input相邻的兄弟label*/ +/*:valid 选择器是判断input 框的内容是否合法,如果合法会执行下面的属性代码, + 不合法就不会执行,我们刚开始写布局的时候给input框写了required 我们删掉看对比 + 当没有required的话 input框的值就会被认为一直合法,所以一直都是下方的样式, + 但是密码不会,密码框的值为空,那么这句话就不合法,required不能为空 + 当我们给密码框写点东西的时候才会执行以下代码 + +*/ +.login .login_box input:focus + label, +.login .login_box input:valid + label{ + top: -20px; + color: #03e9f4; + font-size: 12px; +} + +.login a{ + /*overflow: hidden;*/ + position: relative; + padding: 10px 20px; + color: #03e9f4; + /*取消a表现原有的下划线*/ + text-decoration: none; + /*同样加个过渡*/ + transition: all 0.5s; +} +.login a:hover { + color: #fff; + border-radius: 5px; + background-color: #03e9f4; + box-shadow: 0 0 5px #03e9f4,0 0 25px #03e9f4,0 0 50px #03e9f4,0 0 100px #03e9f4; +} +.login a span{ + position: absolute; +} +.login a span:first-child { + top: 0; + left: -100%; + width: 100%; + height: 2px; + /*to right 就是往右边 下面的同理*/ + background: linear-gradient(to right,transparent,#03e9f4); + /*动画 名称 时长 linear是匀速运动 infinite是无限次运动*/ + animation: move1 1s linear infinite; + +} +.login a span:nth-child(2){ + right: 0; + top: -100%; + width: 2px; + height: 100%; + background: linear-gradient(transparent,#03e6f4); + /*这里多了个0.25s其实是延迟时间*/ + animation: move2 1s linear 0.25s infinite; +} + +.login a span:nth-child(3){ + right: -100%; + bottom: 0; + width: 100%; + height: 2px; + background: linear-gradient(to left,transparent,#03e9f4); + + animation: move3 1s linear 0.5s infinite; +} + +.login a span:last-child{ + left: 0; + bottom: -100%; + width: 2px; + height: 100%; + background: linear-gradient(#03e9f4,transparent); + animation: move4 1s linear 0.75s infinite; +} +/*写一下动画 */ +@keyframes move1{ + 0%{ + left: -100%; + + } + 50%, + 100%{ + left: 100%; + } +} + +@keyframes move2{ + 0%{ + top: -100%; + + } + 50%, + 100%{ + top: 100%; + } +} + +@keyframes move3{ + 0%{ + right: -100%; + + } + 50%, + 100%{ + right: 100%; + } +} + +@keyframes move4{ + 0%{ + bottom: -100%; + + } + 50%, + 100%{ + bottom: 100%; + } +} + +.register-button { + display: block; + width: 100%; + height: 41px; + text-align: center; + background: #add8e6; + border: 3 solid #999; + border-radius: 5px; +} + +.white-text { + color: #fff; /* 设置文本颜色为白色 */ +} + +.attack-button { + background: #add8e6; /* 背景颜色 */ +} diff --git a/TheBattleCar/templates/attacker.html b/TheBattleCar/templates/attacker.html index 24b7d47..b77d886 100644 --- a/TheBattleCar/templates/attacker.html +++ b/TheBattleCar/templates/attacker.html @@ -1,18 +1,22 @@ - + - 攻击者界面 + + + 攻击者 + -

攻击坐标列表

-