@@ -9,13 +9,42 @@ use bin_patch_gen::version::{fetch_spigot_version_meta, fetch_versions};
9
9
use bin_patch_gen:: {
10
10
config, jar, prepare_extraction_path, write_patch, MinecraftVersion , JAR_VERSIONS_PATH ,
11
11
} ;
12
+ use bzip2:: read:: BzDecoder ;
13
+ use clap:: { command, Parser , Subcommand } ;
12
14
use regex:: Regex ;
13
15
use std:: env:: current_dir;
14
- use std:: fs;
16
+ use std:: fs:: { self , File } ;
17
+ use std:: io:: { Read , Write } ;
15
18
use std:: path:: { Path , PathBuf } ;
16
19
use tracing:: info;
17
20
use tracing_subscriber:: fmt:: format;
18
21
22
+ #[ derive( Parser ) ]
23
+ #[ command( about, long_about = None ) ]
24
+ /// The binary patch generator for Sploon.
25
+ struct Cli {
26
+ /// The version to generate for. If not specified, it will generate patches for
27
+ /// all versions of Spigot.
28
+ #[ arg( short, long, value_name = "version" ) ]
29
+ pub version : Option < String > ,
30
+
31
+ #[ command( subcommand) ]
32
+ pub command : Option < Commands > ,
33
+ }
34
+
35
+ #[ derive( Subcommand ) ]
36
+ enum Commands {
37
+ /// Patches a file.
38
+ Patch {
39
+ /// The old file.
40
+ old : PathBuf ,
41
+ /// The new file, patched.
42
+ new : PathBuf ,
43
+ /// The bsdiff patch file, compressed with bzip2.
44
+ patch : PathBuf ,
45
+ } ,
46
+ }
47
+
19
48
#[ tokio:: main]
20
49
async fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
21
50
let fmt = format ( )
@@ -25,6 +54,39 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
25
54
26
55
tracing_subscriber:: fmt ( ) . event_format ( fmt) . init ( ) ;
27
56
57
+ let cli = Cli :: parse ( ) ;
58
+
59
+ if let Some ( Commands :: Patch { old, new, patch } ) = cli. command {
60
+ let patch_file = File :: open ( patch) ?;
61
+ let mut old_file = File :: open ( old) ?;
62
+ let mut new_file = File :: create ( new) ?;
63
+
64
+ let mut old_buf = vec ! [ ] ;
65
+ let mut new_buf = vec ! [ ] ;
66
+
67
+ old_file. read_to_end ( & mut old_buf) ?;
68
+
69
+ let mut decompressor = BzDecoder :: new ( patch_file) ;
70
+
71
+ info ! ( "Patching..." ) ;
72
+ bsdiff:: patch ( & old_buf, & mut decompressor, & mut new_buf) ?;
73
+
74
+ new_file. write_all ( & new_buf) ?;
75
+ info ! ( "Patched!" ) ;
76
+
77
+ return Ok ( ( ) ) ;
78
+ }
79
+
80
+ let versions = if let Some ( version) = cli. version {
81
+ vec ! [ version]
82
+ } else {
83
+ fetch_versions ( ) . await
84
+ } ;
85
+
86
+ run ( versions) . await
87
+ }
88
+
89
+ async fn run ( versions : Vec < String > ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
28
90
let config_file = PathBuf :: from ( "config.toml" ) ;
29
91
if !fs:: exists ( & config_file) ? {
30
92
fs:: write ( config_file, toml:: to_string_pretty ( & Config :: default ( ) ) ?) ?;
@@ -33,9 +95,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
33
95
34
96
let config = config:: read_config ( "config.toml" ) ?;
35
97
36
- info ! ( "Fetching versions..." ) ;
37
- let versions = fetch_versions ( ) . await ;
38
-
39
98
info ! ( "Releases found: {versions:?}" ) ;
40
99
41
100
info ! ( "Downloading BuildTools..." ) ;
@@ -146,7 +205,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
146
205
info ! ( "Diff generated!" ) ;
147
206
148
207
let patched_meta = PatchedVersionMeta {
149
- patch_file : patch_file. file_name ( ) . unwrap ( ) . to_string_lossy ( ) . into_owned ( ) ,
208
+ patch_file : patch_file
209
+ . file_name ( )
210
+ . unwrap ( )
211
+ . to_string_lossy ( )
212
+ . into_owned ( ) ,
150
213
commit_hashes : remote_meta. refs ,
151
214
patch_hash : sha1 ( patch_file) ?,
152
215
patched_jar_hash : sha1 ( spigot_jar) ?,
0 commit comments