33//! Web API and database management service for Minecraft server scanning.
44//! This service can run independently of the scanner service.
55
6+ use migration:: Migrator ;
67use nmcscan_shared:: models:: entities:: { asns, servers} ;
78use nmcscan_shared:: repositories:: {
89 ApiKeyRepository , AsnRepository , ServerRepository , StatsRepository ,
910} ;
1011use nmcscan_shared:: services:: asn_fetcher:: AsnFetcher ;
1112use nmcscan_shared:: utils:: exclude:: { ExcludeList , ExcludeManager } ;
12- use migration:: Migrator ;
13- use sea_orm:: { ColumnTrait , ConnectOptions , Database , EntityTrait , PaginatorTrait , QueryFilter , QuerySelect } ;
13+ use sea_orm:: {
14+ ColumnTrait , ConnectOptions , Database , EntityTrait , PaginatorTrait , QueryFilter , QuerySelect ,
15+ } ;
1416use sea_orm_migration:: MigratorTrait ;
1517use std:: sync:: Arc ;
1618use tracing_subscriber:: { layer:: SubscriberExt , util:: SubscriberInitExt } ;
@@ -21,7 +23,11 @@ mod handlers;
2123
2224/// NMCScan API Service arguments
2325#[ derive( Parser , Debug ) ]
24- #[ command( author, version, about = "NMCScan API Service - Web interface and database management" ) ]
26+ #[ command(
27+ author,
28+ version,
29+ about = "NMCScan API Service - Web interface and database management"
30+ ) ]
2531struct Args {
2632 /// Log level (debug, info, warn, error)
2733 #[ arg( short, long, env = "RUST_LOG" , default_value = "info" ) ]
@@ -104,7 +110,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
104110 tracing:: warn!( "Failed to parse exclude list: {}" , e) ;
105111 ExcludeList :: from_str ( "" ) . unwrap ( )
106112 } ) ;
107- tracing:: info!( "Loaded {} exclude networks (including honeypots)" , exclude_list. len( ) ) ;
113+ tracing:: info!(
114+ "Loaded {} exclude networks (including honeypots)" ,
115+ exclude_list. len( )
116+ ) ;
108117
109118 // 2. Initialize database and run migrations
110119 tracing:: info!( "Initializing database at {}..." , args. database) ;
@@ -126,12 +135,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
126135 let asn_repo = Arc :: new ( AsnRepository :: new ( ( * db) . clone ( ) ) ) ;
127136 let stats_repo = Arc :: new ( StatsRepository :: new ( ( * db) . clone ( ) ) ) ;
128137 let api_key_repo = Arc :: new ( ApiKeyRepository :: new ( ( * db) . clone ( ) ) ) ;
129- let minecraft_account_repo = Arc :: new ( nmcscan_shared:: repositories:: MinecraftAccountRepository :: new ( ( * db) . clone ( ) ) ) ;
138+ let minecraft_account_repo =
139+ Arc :: new ( nmcscan_shared:: repositories:: MinecraftAccountRepository :: new ( ( * db) . clone ( ) ) ) ;
130140
131141 // 4. Initialize ASN fetcher and import/update ASN data
132142 tracing:: info!( "Initializing ASN fetcher..." ) ;
133143 let asn_fetcher = Arc :: new ( AsnFetcher :: new ( Arc :: clone ( & db) , Arc :: clone ( & asn_repo) ) ) ;
134-
144+
135145 // Full import if forced or if data is missing
136146 let range_count = asn_fetcher. asn_manager ( ) . read ( ) . await . range_count ( ) ;
137147 let asn_count = asn_fetcher. asn_manager ( ) . read ( ) . await . asn_count ( ) ;
@@ -162,10 +172,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
162172 . await
163173 . unwrap_or ( 0 ) ;
164174
165- let total_count = asns:: Entity :: find ( )
166- . count ( & * db)
167- . await
168- . unwrap_or ( 1 ) ;
175+ let total_count = asns:: Entity :: find ( ) . count ( & * db) . await . unwrap_or ( 1 ) ;
169176
170177 let unknown_percentage = if total_count > 0 {
171178 ( unknown_count as f64 / total_count as f64 ) * 100.0
@@ -183,7 +190,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
183190 let ipverse_map = asn_fetcher. fetch_ipverse_map ( ) . await ;
184191 match asn_fetcher. recategorize_all_asns ( & ipverse_map) . await {
185192 Ok ( updated) => {
186- tracing:: info!( "Startup recategorization complete: {} ASNs reclassified" , updated) ;
193+ tracing:: info!(
194+ "Startup recategorization complete: {} ASNs reclassified" ,
195+ updated
196+ ) ;
187197 }
188198 Err ( e) => {
189199 tracing:: error!( "Startup recategorization failed: {}" , e) ;
@@ -195,19 +205,20 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
195205 // 5. Backfill ASN data for existing servers
196206 {
197207 let db_clone = Arc :: clone ( & db) ;
198- let servers_res: Result < Vec < servers:: Model > , sea_orm:: DbErr > =
199- servers:: Entity :: find ( )
200- . filter ( servers:: Column :: Asn . is_null ( ) )
201- . filter ( servers:: Column :: Status . ne ( "ignored" ) )
202- . limit ( 5000 )
203- . all ( & * db_clone)
204- . await ;
208+ let servers_res: Result < Vec < servers:: Model > , sea_orm:: DbErr > = servers:: Entity :: find ( )
209+ . filter ( servers:: Column :: Asn . is_null ( ) )
210+ . filter ( servers:: Column :: Status . ne ( "ignored" ) )
211+ . limit ( 5000 )
212+ . all ( & * db_clone)
213+ . await ;
205214 if let Ok ( srvs) = servers_res {
206215 if !srvs. is_empty ( ) {
207216 tracing:: info!( "Backfilling ASN data for {} servers..." , srvs. len( ) ) ;
208217 // Note: Full backfill would require the ASN fetcher to look up each IP
209218 // This is a lighter version for the API service
210- tracing:: info!( "Backfill skipped in API-only mode (scanner will handle on startup)" ) ;
219+ tracing:: info!(
220+ "Backfill skipped in API-only mode (scanner will handle on startup)"
221+ ) ;
211222 }
212223 }
213224 }
@@ -259,7 +270,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
259270 contact_email : args. contact_email . clone ( ) ,
260271 discord_link : args. discord_link . clone ( ) ,
261272 } ;
262-
273+
263274 let listen_addr = args. listen_addr . clone ( ) ;
264275 let listen_addr_log = listen_addr. clone ( ) ;
265276 let api_handle = tokio:: spawn ( async move {
@@ -268,7 +279,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
268279
269280 tracing:: info!( "✅ API Service started on {}" , listen_addr_log) ;
270281 tracing:: info!( " Database: connected" ) ;
271- tracing:: info!( " ASN Manager: initialized ({} ASNs, {} ranges)" , asn_count, range_count) ;
282+ tracing:: info!(
283+ " ASN Manager: initialized ({} ASNs, {} ranges)" ,
284+ asn_count,
285+ range_count
286+ ) ;
272287 tracing:: info!( " Scanner: NOT running (separate nmcscan-scanner service)" ) ;
273288 tracing:: info!( " Login queue: NOT running (part of scanner service)" ) ;
274289
0 commit comments