11import re
22import pyglet
33from widgets import *
4+ from win_tool import *
5+ from ping3 import ping
46from typing import Dict
57from ttkbootstrap import Style
68from info_gui import InfoWindow
7- from subprocess import getoutput
89from scanner import ServerScanner
910from threading import Thread , Lock
1011from tkinter import font , filedialog
1112from base64 import b64decode , b64encode
1213from pyperclip import copy as copy_clipboard
1314from ttkbootstrap .scrolled import ScrolledFrame
14- from json import load as json_load , dump as json_dump , JSONDecodeError
1515from time import perf_counter , sleep , time , strftime
1616from pickle import loads as pickle_loads , dumps as pickle_dumps
17+ from json import load as json_load , dump as json_dump , JSONDecodeError
1718from win32con import MB_ICONWARNING , MB_YESNOCANCEL , IDYES , MB_ICONERROR , MB_OK , MB_YESNO , MB_ICONQUESTION , IDNO , \
1819 IDCANCEL
1920from win32gui import MessageBox , FindWindow , FindWindowEx , GetParent , EnumChildWindows , GetWindowText , SetWindowText
@@ -30,12 +31,6 @@ def load_unifont():
3031 pyglet .font .add_file ("assets/Unifont.otf" )
3132
3233
33- def ping_host (host : str ) -> bool :
34- cmd = f"ping -n 1 { host } "
35- output = getoutput (cmd )
36- return "丢失 = 0" in output
37-
38-
3934def write_msg_window_buttons (left : str , right : str , timeout : float = 1.2 ):
4035 def callback (hwnd : int , _ ):
4136 if GetWindowText (hwnd ) == "是(&Y)" :
@@ -58,6 +53,16 @@ def callback(hwnd: int, _):
5853 break
5954
6055
56+ def get_hwnd_main_hwnd (hwnd : int ):
57+ while True :
58+ print (hwnd , "P:" , GetParent (hwnd ))
59+ if GetParent (hwnd ) != 0 :
60+ hwnd = GetParent (hwnd )
61+ else :
62+ break
63+ return hwnd
64+
65+
6166class GUI (ttk .Window ):
6267 def __init__ (self ):
6368 super (GUI , self ).__init__ ()
@@ -83,6 +88,7 @@ def config_root_window(self): # 设置窗体
8388 self .wm_title ("MC服务器扫描器" ) # 设置标题
8489 self .style .theme_use ("solar" )
8590 self .wm_geometry ("754x730" )
91+ self .wm_resizable (False , False )
8692 Thread (target = self .wm_iconbitmap , args = ("assets/icon.ico" ,)).start ()
8793 Thread (target = self .place_window_center ).start ()
8894
@@ -541,7 +547,7 @@ def __init__(self, master: Misc, interval: float, text: str):
541547 self .last_value = 0
542548 self .last_update = time ()
543549 self .speed_avg = []
544- self ._max = 0
550+ self .max_ = 0
545551 self .interval = interval
546552
547553 self .text = ttk .Label (self , text = text )
@@ -556,7 +562,7 @@ def reset(self, _max: int):
556562 self .last_value = 0
557563 self .last_update = time ()
558564 self .speed_avg .clear ()
559- self ._max = _max
565+ self .max_ = _max
560566 self .progress_text .configure (text = "0 ports/s" )
561567 self .progress .set_percentage (0 , "0%" )
562568
@@ -573,7 +579,7 @@ def update_now(self, value: float):
573579 elif len (self .speed_avg ) == 0 :
574580 self .speed_avg .append (0 )
575581
576- percentage = value / self ._max
582+ percentage = value / self .max_
577583 self .progress .set_percentage (percentage , f"{ round (percentage * 100 , 2 )} %" )
578584 self .update_progress_text (sum (self .speed_avg ) / len (self .speed_avg ))
579585
@@ -582,7 +588,7 @@ def update_now(self, value: float):
582588 self .last_update = time ()
583589
584590 def finish (self ):
585- self .update_now (self ._max )
591+ self .update_now (self .max_ )
586592 self .update_progress_text (0 )
587593
588594
@@ -594,27 +600,38 @@ def __init__(self, master: Misc, text: str = "0%"):
594600 self .bind ("<<ThemeChanged>>" , self .change_color )
595601 self .percentage = 0
596602 self .text = text
597- self .redraw ()
603+ self .now_elements = []
604+ self .last_elements = []
605+
606+ self .text_id = self .create_text (self .winfo_width () // 2 , 13 , text = self .text , fill = self .color .fg )
607+ self .last_elements .append (self .text_id )
598608
599609 def change_color (self , * _ ):
600610 self .color = Style ().colors
601611 self .redraw ()
602612
603613 def redraw (self , * _ ):
604- self .delete ( ALL )
614+ self .now_elements . clear ( )
605615 width = self .winfo_width ()
606616 bar_x = int ((width - 4 ) * self .percentage )
607617 if bar_x == 1 :
608- self .create_line (1 , 1 , 1 , 26 , fill = self .color .success )
618+ self .now_elements . append ( self . create_line (1 , 1 , 1 , 26 , fill = self .color .success ) )
609619 elif bar_x > 1 :
610- self .create_rectangle (1 , 1 , bar_x , 26 - 2 , fill = self .color .success , outline = self .color .success ) # 06B025
620+ self .now_elements .append (self .create_rectangle (1 , 1 , bar_x , 26 - 2 , fill = self .color .success ,
621+ outline = self .color .success ))
622+
623+ self .now_elements .append (self .create_rectangle (0 , 0 , width - 1 , 26 - 1 , outline = self .color .border ))
624+ self .text_id = self .create_text (width // 2 , 13 , text = self .text , fill = self .color .fg )
625+ self .now_elements .append (self .text_id )
611626
612- self .create_rectangle (0 , 0 , width - 1 , 26 - 1 , outline = self .color .border )
613- self .create_text (width // 2 , 13 , text = self .text , fill = self .color .fg )
627+ if self .last_elements :
628+ self .delete (* self .last_elements )
629+ self .last_elements = self .now_elements .copy ()
614630
615631 def set_percentage (self , percentage : float , text : str = None ):
616632 self .percentage = percentage
617633 self .text = text if text is not None else self .text
634+ self .itemconfig (self .text_id , text = self .text )
618635 self .redraw ()
619636
620637
@@ -804,6 +821,8 @@ def __init__(self, master: Misc, logger: Logger, server_list: ServerList):
804821 self .callback_lock = Lock ()
805822 self .progress_var = 0
806823 self .callback_workers = 0
824+ self .taskbar = None
825+ self .after (100 , self .taskbar_create )
807826
808827 # 进度条
809828 self .progress_bar = InfoProgressBar (self , interval = 0.05 , text = "扫描进度: " )
@@ -832,7 +851,7 @@ def __init__(self, master: Misc, logger: Logger, server_list: ServerList):
832851
833852 # 扫描控制 Frame
834853 self .buttons = ttk .Frame (self )
835- self .start_button = ttk .Button (self .buttons , text = "开始扫描" , command = self .start_scan )
854+ self .start_button = ttk .Button (self .buttons , text = "开始扫描" , command = self .start_scan , state = DISABLED )
836855 self .pause_button = PauseButton (self .buttons , self .resume_scan , self .pause_scan , state = DISABLED )
837856 self .stop_button = ttk .Button (self .buttons , text = "停止" , command = self .stop_scan , state = DISABLED )
838857
@@ -841,12 +860,17 @@ def __init__(self, master: Misc, logger: Logger, server_list: ServerList):
841860 self .pause_button .pack (fill = X , expand = True , pady = 2 )
842861 self .stop_button .pack (fill = X , expand = True , pady = 2 )
843862
863+ def taskbar_create (self ):
864+ self .taskbar = TaskbarApi (FindWindow ("TkTopLevel" , "MC服务器扫描器" ))
865+ self .start_button .configure (state = NORMAL )
866+
844867 def callback (self , info : Any ):
845868 if not self .in_scan :
846869 return
847870 with self .callback_lock :
848871 self .progress_var += 1
849872 self .progress_bar .update_progress (self .progress_var )
873+ self .taskbar .SetProgressValue (self .progress_var , self .progress_bar .max_ )
850874 if isinstance (info , ServerInfo ):
851875 self .server_list .add_server (info )
852876 self .logger .log (INFO , f"[{ info .port } ]:" , "检测到MC服务器" )
@@ -877,6 +901,7 @@ def start_scan(self, start: int = None, stop: int = None): # 20500 - 25000
877901 self .scan_obj .config (host , timeout , thread_num )
878902 Thread (target = self .scan_obj .run , args = (range (start , stop ), self .callback )).start ()
879903 Thread (target = self .check_over_thread , daemon = True ).start ()
904+ self .taskbar .SetProgressState (TBPFLAG .TBPF_NORMAL )
880905
881906 def pause_scan (self ):
882907 def task ():
@@ -890,6 +915,7 @@ def task():
890915 self .pause_button .configure (state = NORMAL )
891916
892917 Thread (target = task , daemon = True ).start ()
918+ self .taskbar .SetProgressState (TBPFLAG .TBPF_PAUSED )
893919
894920 def resume_scan (self ):
895921 def task ():
@@ -902,6 +928,7 @@ def task():
902928 self .pause_button .configure (state = NORMAL )
903929
904930 Thread (target = task , daemon = True ).start ()
931+ self .taskbar .SetProgressState (TBPFLAG .TBPF_NORMAL )
905932
906933 def stop_scan (self ):
907934 if not self .in_scan :
@@ -913,14 +940,17 @@ def stop_scan(self):
913940 def stop_task ():
914941 self .in_scan = False
915942 self .scan_obj .stop ()
943+ self .logger .log (INFO , "停止扫描" )
916944 while self .scan_obj .worker_count != 0 :
917945 sleep (0.1 )
918946 self .logger .log (INFO , "等待线程结束, 剩余工作线程线程数量:" , self .scan_obj .worker_count )
919947 self .logger .log (INFO , "线程已全部结束" )
920948 self .start_button .configure (state = NORMAL )
949+ self .taskbar .SetProgressState (TBPFLAG .TBPF_NOPROGRESS )
921950 self .progress_stop ()
922951
923952 Thread (target = stop_task ).start ()
953+ self .taskbar .SetProgressState (TBPFLAG .TBPF_INDETERMINATE )
924954
925955 def check_over_thread (self ):
926956 if not self .in_scan :
@@ -934,10 +964,11 @@ def check_over_thread(self):
934964 self .pause_button .configure (state = DISABLED )
935965 self .start_button .configure (state = NORMAL )
936966 self .progress_stop ()
967+ FlashWindowCount (FindWindow ("TkTopLevel" , "MC服务器扫描器" ))
937968
938969 def progress_stop (self ):
939970 self .progress_bar .update_now (self .progress_var )
940- self .progress_bar .finish ()
971+ # self.progress_bar.finish()
941972
942973 def check_host (self , host : str ) -> bool :
943974 self .logger .log (INFO , f"检测域名 [{ host } ] ..." )
@@ -952,8 +983,9 @@ def check_host(self, host: str) -> bool:
952983 return False
953984
954985 self .logger .log (INFO , "开始ping测试..." )
955- if ping_host (host ):
956- self .logger .log (INFO , "域名存活" )
986+ delay = ping (host )
987+ if delay is not None :
988+ self .logger .log (INFO , f"域名存活, 延迟: { round (delay * 1000 , 2 )} ms" )
957989 return True
958990 else :
959991 self .logger .log (ERROR , "域名无法连接" )
0 commit comments