Skip to content

Commit 2c31d26

Browse files
authored
Merge pull request #630 from louis-e/crash-telemetry
WIP: Crash telemetry collection
2 parents 834ce7b + 996e06a commit 2c31d26

File tree

11 files changed

+442
-20
lines changed

11 files changed

+442
-20
lines changed

src/data_processing.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::element_processing::*;
66
use crate::ground::Ground;
77
use crate::osm_parser::ProcessedElement;
88
use crate::progress::emit_gui_progress_update;
9+
use crate::telemetry::{send_log, LogLevel};
910
use crate::world_editor::WorldEditor;
1011
use colored::Colorize;
1112
use indicatif::{ProgressBar, ProgressStyle};
@@ -250,7 +251,9 @@ pub fn generate_world(
250251
args.scale,
251252
&ground,
252253
) {
253-
eprintln!("Warning: Failed to update spawn point Y coordinate: {e}");
254+
let warning_msg = format!("Failed to update spawn point Y coordinate: {}", e);
255+
eprintln!("Warning: {}", warning_msg);
256+
send_log(LogLevel::Warning, &warning_msg);
254257
}
255258
}
256259

src/elevation_data.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::coordinate_system::{geographic::LLBBox, transformation::geo_distance};
2+
use crate::telemetry::{send_log, LogLevel};
23
use image::Rgb;
34
use std::path::Path;
45

@@ -109,15 +110,26 @@ pub fn fetch_elevation_data(
109110
};
110111

111112
if file_size < 1000 {
112-
eprintln!("Warning: Cached tile at {} appears to be too small ({} bytes). Refetching tile.",
113-
tile_path.display(), file_size);
113+
eprintln!(
114+
"Warning: Cached tile at {} appears to be too small ({} bytes). Refetching tile.",
115+
tile_path.display(),
116+
file_size
117+
);
118+
send_log(
119+
LogLevel::Warning,
120+
"Cached tile appears to be too small. Refetching tile.",
121+
);
114122

115123
// Remove the potentially corrupted file
116124
if let Err(remove_err) = std::fs::remove_file(&tile_path) {
117125
eprintln!(
118126
"Warning: Failed to remove corrupted tile file: {}",
119127
remove_err
120128
);
129+
send_log(
130+
LogLevel::Warning,
131+
"Failed to remove corrupted tile file during refetching.",
132+
);
121133
}
122134

123135
// Re-download the tile
@@ -132,14 +144,26 @@ pub fn fetch_elevation_data(
132144
match image::open(&tile_path) {
133145
Ok(img) => img.to_rgb8(),
134146
Err(e) => {
135-
eprintln!("Warning: Cached tile at {} is corrupted or invalid: {}. Re-downloading...", tile_path.display(), e);
147+
eprintln!(
148+
"Cached tile at {} is corrupted or invalid: {}. Re-downloading...",
149+
tile_path.display(),
150+
e
151+
);
152+
send_log(
153+
LogLevel::Warning,
154+
"Cached tile is corrupted or invalid. Re-downloading...",
155+
);
136156

137157
// Remove the corrupted file
138158
if let Err(remove_err) = std::fs::remove_file(&tile_path) {
139159
eprintln!(
140160
"Warning: Failed to remove corrupted tile file: {}",
141161
remove_err
142162
);
163+
send_log(
164+
LogLevel::Warning,
165+
"Failed to remove corrupted tile file during re-download.",
166+
);
143167
}
144168

145169
// Re-download the tile

src/gui.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,16 @@ use crate::map_transformation;
88
use crate::osm_parser;
99
use crate::progress;
1010
use crate::retrieve_data;
11+
use crate::telemetry::{self, send_log, LogLevel};
1112
use crate::version_check;
1213
use fastnbt::Value;
1314
use flate2::read::GzDecoder;
1415
use fs2::FileExt;
15-
use log::{error, LevelFilter};
16+
use log::LevelFilter;
1617
use rfd::FileDialog;
1718
use std::io::Read;
1819
use std::path::{Path, PathBuf};
19-
use std::{env, fs, io::Write, panic};
20+
use std::{env, fs, io::Write};
2021
use tauri_plugin_log::{Builder as LogBuilder, Target, TargetKind};
2122

2223
/// Manages the session.lock file for a Minecraft world directory
@@ -63,12 +64,8 @@ pub fn run_gui() {
6364
// Launch the UI
6465
println!("Launching UI...");
6566

66-
// Set a custom panic hook to log panic information
67-
panic::set_hook(Box::new(|panic_info| {
68-
let message = format!("Application panicked: {panic_info:?}");
69-
error!("{message}");
70-
std::process::exit(1);
71-
}));
67+
// Install panic hook for crash reporting
68+
telemetry::install_panic_hook();
7269

7370
// Workaround WebKit2GTK issue with NVIDIA drivers and graphics issues
7471
// Source: https://github.com/tauri-apps/tauri/issues/10702
@@ -400,6 +397,10 @@ fn add_localized_world_name(world_path: PathBuf, bbox: &LLBBox) -> PathBuf {
400397
if let Ok(compressed_data) = encoder.finish() {
401398
if let Err(e) = std::fs::write(&level_path, compressed_data) {
402399
eprintln!("Failed to update level.dat with area name: {e}");
400+
send_log(
401+
LogLevel::Warning,
402+
"Failed to update level.dat with area name",
403+
);
403404
}
404405
}
405406
}
@@ -678,10 +679,17 @@ fn gui_start_generation(
678679
fillground_enabled: bool,
679680
is_new_world: bool,
680681
spawn_point: Option<(f64, f64)>,
682+
telemetry_consent: bool,
681683
) -> Result<(), String> {
682684
use progress::emit_gui_error;
683685
use LLBBox;
684686

687+
// Store telemetry consent for crash reporting
688+
telemetry::set_telemetry_consent(telemetry_consent);
689+
690+
// Send generation click telemetry
691+
telemetry::send_generation_click();
692+
685693
// If spawn point was chosen and the world is new, check and set the spawn point
686694
if is_new_world && spawn_point.is_some() {
687695
// Verify the spawn point is within bounds
@@ -810,6 +818,7 @@ fn gui_start_generation(
810818
&mut xzbbox,
811819
&mut ground,
812820
);
821+
send_log(LogLevel::Info, "Map transformation completed.");
813822

814823
let _ = data_processing::generate_world(
815824
parsed_elements,

src/gui/css/styles.css

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ a:hover {
6363
justify-content: center;
6464
align-items: stretch;
6565
margin-top: 5px;
66+
min-height: 60vh;
6667
}
6768

6869
.section {
@@ -79,6 +80,12 @@ a:hover {
7980
padding: 20px;
8081
border-radius: 8px;
8182
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
83+
display: flex;
84+
flex-direction: column;
85+
}
86+
87+
.map-box {
88+
min-height: 400px;
8289
}
8390

8491
.controls-content {
@@ -94,6 +101,8 @@ a:hover {
94101
.map-container {
95102
border: 2px solid #e0e0e0;
96103
border-radius: 8px;
104+
flex-grow: 1;
105+
min-height: 300px;
97106
}
98107

99108
.section h2 {
@@ -249,6 +258,33 @@ button:hover {
249258
color: #ffffff;
250259
}
251260

261+
/* Modal actions/buttons */
262+
.modal-actions {
263+
display: flex;
264+
justify-content: flex-end;
265+
gap: 10px;
266+
}
267+
268+
.btn-primary {
269+
background-color: var(--primary-accent);
270+
color: #1a1a1a;
271+
}
272+
273+
.btn-primary:hover {
274+
background-color: var(--primary-accent-dark);
275+
}
276+
277+
.btn-secondary {
278+
background-color: #e0e0e0;
279+
}
280+
281+
@media (prefers-color-scheme: dark) {
282+
.btn-secondary {
283+
background-color: #3a3a3a;
284+
color: #ffffff;
285+
}
286+
}
287+
252288
#terrain-toggle {
253289
accent-color: #fecc44;
254290
}
@@ -281,6 +317,10 @@ button:hover {
281317
margin: 15px 0;
282318
}
283319

320+
#telemetry-toggle {
321+
accent-color: #fecc44;
322+
}
323+
284324
.scale-slider-container label {
285325
display: block;
286326
margin-bottom: 5px;
@@ -306,7 +346,7 @@ button:hover {
306346

307347
#bbox-coords {
308348
width: 100%;
309-
padding: 8px;
349+
padding: 5px;
310350
border: 1px solid #fecc44;
311351
border-radius: 4px;
312352
font-size: 14px;
@@ -353,7 +393,7 @@ button:hover {
353393

354394
.license-button-row {
355395
justify-content: center;
356-
margin-top: 10px;
396+
margin-top: 5px;
357397
}
358398

359399
.license-button {
@@ -393,7 +433,7 @@ button:hover {
393433
.generation-mode-dropdown {
394434
width: 100%;
395435
max-width: 180px;
396-
padding: 5px 8px;
436+
padding: 3px 8px;
397437
border-radius: 4px;
398438
border: 1px solid #fecc44;
399439
background-color: #ffffff;
@@ -421,7 +461,7 @@ button:hover {
421461
.language-dropdown {
422462
width: 100%;
423463
max-width: 180px;
424-
padding: 5px 8px;
464+
padding: 3px 8px;
425465
border-radius: 4px;
426466
border: 1px solid #fecc44;
427467
background-color: #ffffff;
@@ -449,7 +489,7 @@ button:hover {
449489
.theme-dropdown {
450490
width: 100%;
451491
max-width: 180px;
452-
padding: 5px 8px;
492+
padding: 3px 8px;
453493
border-radius: 4px;
454494
border: 1px solid #fecc44;
455495
background-color: #ffffff;

src/gui/index.html

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,14 @@ <h2 data-localize="customization_settings">Customization Settings</h2>
186186
</div>
187187
</div>
188188

189+
<!-- Telemetry Consent Toggle -->
190+
<div class="settings-row">
191+
<label for="telemetry-toggle">Anonymous Crash Reports</label>
192+
<div class="settings-control">
193+
<input type="checkbox" id="telemetry-toggle" name="telemetry-toggle">
194+
</div>
195+
</div>
196+
189197
<!-- License and Credits Button -->
190198
<div class="settings-row license-button-row">
191199
<button type="button" id="license-button" class="license-button" onclick="openLicense()" data-localize="license_and_credits">License and Credits</button>
@@ -203,6 +211,22 @@ <h2 data-localize="customization_settings">Customization Settings</h2>
203211
</div>
204212
</div>
205213

214+
<!-- Telemetry Consent Modal (first run) -->
215+
<div id="telemetry-modal" class="modal" style="display: none;">
216+
<div class="modal-content">
217+
<span class="close-button" onclick="rejectTelemetry()">&times;</span>
218+
<h2>Help improve Arnis</h2>
219+
<p style="text-align:left; margin-top:6px; color:#ececec;">
220+
We’d like to collect anonymous usage data like crashes and performance to make Arnis more stable and faster.
221+
<a href="https://arnismc.com/privacypolicy.html" style="color: inherit;" target="_blank">No personal data or world contents are collected.</a>
222+
</p>
223+
<div class="modal-actions" style="margin-top:14px;">
224+
<button type="button" class="btn-secondary" onclick="rejectTelemetry()">No thanks</button>
225+
<button type="button" class="btn-primary" onclick="acceptTelemetry()">Allow anonymous data</button>
226+
</div>
227+
</div>
228+
</div>
229+
206230
<!-- License Modal -->
207231
<div id="license-modal" class="modal" style="display: none;">
208232
<div class="modal-content">

src/gui/js/license.js

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)