@@ -68,8 +68,7 @@ def display_vpk_contents(self, file=""):
68
68
self .populate_tree (files )
69
69
70
70
self .tree .bind ("<Double-Button-1>" , self .open_file_in_vpk )
71
-
72
- #self.fileList = FileListApp(self.sdk, self.root)
71
+ self .tree .bind ("<Button-3>" , self .show_context_menu )
73
72
74
73
def list_vpk_files (self ):
75
74
"""
@@ -193,7 +192,44 @@ def extract_file(path):
193
192
os .startfile (primary_temp_path )
194
193
except Exception as e :
195
194
print (f"Failed to open file { primary_temp_path } : { e } " )
196
-
195
+
196
+ def extract_and_save_file (self , file_name , destination_folder ):
197
+ """
198
+ Extract a file from the VPK archive to a specified folder.
199
+ """
200
+ if not self .vpk_file :
201
+ print ("VPK file is not loaded." )
202
+ return
203
+
204
+ related_extensions = [".dx80.vtx" , ".dx90.vtx" , ".sw.vtx" , ".phy" , ".vvd" ]
205
+
206
+ def extract_file (path ):
207
+ pakfile = self .vpk_file .get_file (path )
208
+ if pakfile :
209
+ file_content = pakfile .read ()
210
+ temp_file_path = os .path .join (destination_folder , os .path .basename (path ))
211
+ with open (temp_file_path , 'wb' ) as temp_file :
212
+ temp_file .write (file_content )
213
+ return temp_file_path
214
+ return None
215
+
216
+ # Extract the primary file
217
+ primary_temp_path = extract_file (file_name )
218
+ if not primary_temp_path :
219
+ print (f"File { file_name } not found in VPK." )
220
+ return
221
+
222
+ # Extract related files for .mdl if required
223
+ if file_name .endswith (".mdl" ):
224
+ base_name = os .path .splitext (file_name )[0 ]
225
+ for ext in related_extensions :
226
+ try :
227
+ extract_file (base_name + ext )
228
+ except OSError :
229
+ print ("mdl error" )
230
+
231
+ print (f"File { file_name } extracted to { destination_folder } " )
232
+
197
233
def create_VPK (self ):
198
234
"""
199
235
Create a VPK file from a selected directory.
@@ -255,3 +291,34 @@ def clear_selections(self):
255
291
for item in self .tree .selection ():
256
292
self .tree .selection_remove (item )
257
293
294
+ def show_context_menu (self , event ):
295
+ """
296
+ Show the context menu on right-click.
297
+ """
298
+ selected_item = self .tree .identify_row (event .y )
299
+ if selected_item :
300
+ self .tree .selection_set (selected_item )
301
+ self .context_menu = tk .Menu (self .tree , tearoff = 0 )
302
+ self .context_menu .add_command (label = "Extract to..." , command = self .extract_to )
303
+ self .context_menu .post (event .x_root , event .y_root )
304
+
305
+ def extract_to (self ):
306
+ """
307
+ Extract the selected file to a user-selected folder.
308
+ """
309
+ selected_item = self .tree .selection ()[0 ]
310
+ item_text = self .tree .item (selected_item , "text" )
311
+ parent_item = self .tree .parent (selected_item )
312
+ file_path_parts = [item_text ]
313
+
314
+ while parent_item :
315
+ item_text = self .tree .item (parent_item , "text" )
316
+ file_path_parts .append (item_text )
317
+ parent_item = self .tree .parent (parent_item )
318
+
319
+ file_path_parts .reverse ()
320
+ file_path = "/" .join (file_path_parts ) # Use '/' as VPK paths use forward slashes
321
+
322
+ destination_folder = filedialog .askdirectory (title = "Select Destination Folder" )
323
+ if destination_folder :
324
+ self .extract_and_save_file (file_path , destination_folder )
0 commit comments