Explorar el Código

[FL-2828] Dolphin score update take 2 (#1929)

* Move DolphinDeedNfcRead
* Move DolphinDeedNfcReadSuccess
* Move DolphinDeedNfcSave
* Move DolphinDeedNfcDetectReader
* Move DolphinDeedNfcEmulate
* Count DolphinDeedNfcEmulate when launched from file browser
* Implement most of the score accounting for NFC
* Fully update Nfc icounter handling
* Move DolphinDeedSubGhzFrequencyAnalyzer
* Update the rest of icounter in SubGHz
* Adjust SubGHz icounter handling
* Adjust LFRFID icounter handling
* Adjust Infrared icounter handling
* Don't count renaming RFID tags as saving
* Don't count renaming SubGHz signals as saving
* Don't count renaming NFC tags as saving
* Adjust iButton icounter handling
* Minor code refactoring
* Correct formatting
* Account for emulating iButton keys from file manager/rpc

Co-authored-by: あく <alleteam@gmail.com>
Georgii Surkov hace 3 años
padre
commit
f11df49468
Se han modificado 59 ficheros con 125 adiciones y 72 borrados
  1. 3 0
      applications/main/ibutton/ibutton.c
  2. 0 3
      applications/main/ibutton/scenes/ibutton_scene_add_value.c
  3. 0 3
      applications/main/ibutton/scenes/ibutton_scene_emulate.c
  4. 1 2
      applications/main/ibutton/scenes/ibutton_scene_read.c
  5. 2 0
      applications/main/ibutton/scenes/ibutton_scene_read_key_menu.c
  6. 10 0
      applications/main/ibutton/scenes/ibutton_scene_save_name.c
  7. 0 2
      applications/main/ibutton/scenes/ibutton_scene_save_success.c
  8. 2 0
      applications/main/ibutton/scenes/ibutton_scene_saved_key_menu.c
  9. 2 0
      applications/main/ibutton/scenes/ibutton_scene_start.c
  10. 2 0
      applications/main/infrared/scenes/infrared_scene_learn.c
  11. 0 3
      applications/main/infrared/scenes/infrared_scene_learn_done.c
  12. 2 0
      applications/main/infrared/scenes/infrared_scene_learn_enter_name.c
  13. 0 3
      applications/main/infrared/scenes/infrared_scene_learn_success.c
  14. 4 1
      applications/main/lfrfid/lfrfid.c
  15. 0 3
      applications/main/lfrfid/scenes/lfrfid_scene_emulate.c
  16. 3 0
      applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c
  17. 1 2
      applications/main/lfrfid/scenes/lfrfid_scene_read.c
  18. 2 0
      applications/main/lfrfid/scenes/lfrfid_scene_read_key_menu.c
  19. 0 2
      applications/main/lfrfid/scenes/lfrfid_scene_save_data.c
  20. 8 0
      applications/main/lfrfid/scenes/lfrfid_scene_save_name.c
  21. 0 2
      applications/main/lfrfid/scenes/lfrfid_scene_save_success.c
  22. 2 0
      applications/main/lfrfid/scenes/lfrfid_scene_saved_key_menu.c
  23. 2 0
      applications/main/lfrfid/scenes/lfrfid_scene_start.c
  24. 4 0
      applications/main/nfc/nfc.c
  25. 0 2
      applications/main/nfc/scenes/nfc_scene_detect_reader.c
  26. 0 2
      applications/main/nfc/scenes/nfc_scene_emulate_uid.c
  27. 0 2
      applications/main/nfc/scenes/nfc_scene_emv_read_success.c
  28. 4 0
      applications/main/nfc/scenes/nfc_scene_mf_classic_dict_attack.c
  29. 0 2
      applications/main/nfc/scenes/nfc_scene_mf_classic_emulate.c
  30. 2 0
      applications/main/nfc/scenes/nfc_scene_mf_classic_keys_add.c
  31. 5 2
      applications/main/nfc/scenes/nfc_scene_mf_classic_menu.c
  32. 0 3
      applications/main/nfc/scenes/nfc_scene_mf_classic_read_success.c
  33. 6 0
      applications/main/nfc/scenes/nfc_scene_mf_desfire_menu.c
  34. 0 2
      applications/main/nfc/scenes/nfc_scene_mf_ultralight_emulate.c
  35. 6 0
      applications/main/nfc/scenes/nfc_scene_mf_ultralight_menu.c
  36. 0 2
      applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_auth.c
  37. 0 4
      applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_auth_result.c
  38. 0 2
      applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_success.c
  39. 2 0
      applications/main/nfc/scenes/nfc_scene_mf_ultralight_unlock_warn.c
  40. 6 0
      applications/main/nfc/scenes/nfc_scene_nfca_menu.c
  41. 0 3
      applications/main/nfc/scenes/nfc_scene_nfca_read_success.c
  42. 6 1
      applications/main/nfc/scenes/nfc_scene_read.c
  43. 0 2
      applications/main/nfc/scenes/nfc_scene_read_card_success.c
  44. 8 0
      applications/main/nfc/scenes/nfc_scene_save_name.c
  45. 0 2
      applications/main/nfc/scenes/nfc_scene_save_success.c
  46. 2 0
      applications/main/nfc/scenes/nfc_scene_saved_menu.c
  47. 0 2
      applications/main/nfc/scenes/nfc_scene_set_uid.c
  48. 3 0
      applications/main/nfc/scenes/nfc_scene_start.c
  49. 0 2
      applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c
  50. 6 1
      applications/main/subghz/scenes/subghz_scene_read_raw.c
  51. 2 0
      applications/main/subghz/scenes/subghz_scene_receiver.c
  52. 0 2
      applications/main/subghz/scenes/subghz_scene_receiver_info.c
  53. 12 0
      applications/main/subghz/scenes/subghz_scene_save_name.c
  54. 0 3
      applications/main/subghz/scenes/subghz_scene_save_success.c
  55. 0 2
      applications/main/subghz/scenes/subghz_scene_set_type.c
  56. 2 0
      applications/main/subghz/scenes/subghz_scene_start.c
  57. 1 1
      applications/main/subghz/scenes/subghz_scene_transmitter.c
  58. 1 1
      applications/services/dolphin/helpers/dolphin_deed.c
  59. 1 1
      applications/services/dolphin/helpers/dolphin_deed.h

+ 3 - 0
applications/main/ibutton/ibutton.c

@@ -5,6 +5,7 @@
 #include <toolbox/path.h>
 #include <flipper_format/flipper_format.h>
 #include <rpc/rpc_app.h>
+#include <dolphin/dolphin.h>
 
 #define TAG "iButtonApp"
 
@@ -337,11 +338,13 @@ int32_t ibutton_app(void* p) {
         view_dispatcher_attach_to_gui(
             ibutton->view_dispatcher, ibutton->gui, ViewDispatcherTypeDesktop);
         scene_manager_next_scene(ibutton->scene_manager, iButtonSceneRpc);
+        DOLPHIN_DEED(DolphinDeedIbuttonEmulate);
     } else {
         view_dispatcher_attach_to_gui(
             ibutton->view_dispatcher, ibutton->gui, ViewDispatcherTypeFullscreen);
         if(key_loaded) {
             scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate);
+            DOLPHIN_DEED(DolphinDeedIbuttonEmulate);
         } else {
             scene_manager_next_scene(ibutton->scene_manager, iButtonSceneStart);
         }

+ 0 - 3
applications/main/ibutton/scenes/ibutton_scene_add_value.c

@@ -1,7 +1,5 @@
 #include "../ibutton_i.h"
 
-#include <dolphin/dolphin.h>
-
 void ibutton_scene_add_type_byte_input_callback(void* context) {
     iButton* ibutton = context;
     view_dispatcher_send_custom_event(ibutton->view_dispatcher, iButtonCustomEventByteEditResult);
@@ -38,7 +36,6 @@ bool ibutton_scene_add_value_on_event(void* context, SceneManagerEvent event) {
         consumed = true;
         if(event.event == iButtonCustomEventByteEditResult) {
             ibutton_key_set_data(ibutton->key, new_key_data, IBUTTON_KEY_DATA_SIZE);
-            DOLPHIN_DEED(DolphinDeedIbuttonAdd);
             scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSaveName);
         }
     }

+ 0 - 3
applications/main/ibutton/scenes/ibutton_scene_emulate.c

@@ -1,6 +1,5 @@
 #include "../ibutton_i.h"
 #include <core/log.h>
-#include <dolphin/dolphin.h>
 #include <toolbox/path.h>
 
 #define EMULATE_TIMEOUT_TICKS 10
@@ -26,8 +25,6 @@ void ibutton_scene_emulate_on_enter(void* context) {
         path_extract_filename(ibutton->file_path, key_name, true);
     }
 
-    DOLPHIN_DEED(DolphinDeedIbuttonEmulate);
-
     // check that stored key has name
     if(!furi_string_empty(key_name)) {
         ibutton_text_store_set(ibutton, "%s", furi_string_get_cstr(key_name));

+ 1 - 2
applications/main/ibutton/scenes/ibutton_scene_read.c

@@ -11,7 +11,6 @@ void ibutton_scene_read_on_enter(void* context) {
     Popup* popup = ibutton->popup;
     iButtonKey* key = ibutton->key;
     iButtonWorker* worker = ibutton->key_worker;
-    DOLPHIN_DEED(DolphinDeedIbuttonRead);
 
     popup_set_header(popup, "iButton", 95, 26, AlignCenter, AlignBottom);
     popup_set_text(popup, "Waiting\nfor key ...", 95, 30, AlignCenter, AlignTop);
@@ -54,8 +53,8 @@ bool ibutton_scene_read_on_event(void* context, SceneManagerEvent event) {
             if(success) {
                 ibutton_notification_message(ibutton, iButtonNotificationMessageSuccess);
                 ibutton_notification_message(ibutton, iButtonNotificationMessageGreenOn);
-                DOLPHIN_DEED(DolphinDeedIbuttonReadSuccess);
                 scene_manager_next_scene(scene_manager, iButtonSceneReadSuccess);
+                DOLPHIN_DEED(DolphinDeedIbuttonReadSuccess);
             }
         }
     }

+ 2 - 0
applications/main/ibutton/scenes/ibutton_scene_read_key_menu.c

@@ -1,4 +1,5 @@
 #include "../ibutton_i.h"
+#include <dolphin/dolphin.h>
 
 typedef enum {
     SubmenuIndexSave,
@@ -49,6 +50,7 @@ bool ibutton_scene_read_key_menu_on_event(void* context, SceneManagerEvent event
             scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSaveName);
         } else if(event.event == SubmenuIndexEmulate) {
             scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate);
+            DOLPHIN_DEED(DolphinDeedIbuttonEmulate);
         } else if(event.event == SubmenuIndexWrite) {
             scene_manager_next_scene(ibutton->scene_manager, iButtonSceneWrite);
         }

+ 10 - 0
applications/main/ibutton/scenes/ibutton_scene_save_name.c

@@ -1,6 +1,7 @@
 #include "../ibutton_i.h"
 #include <lib/toolbox/random_name.h>
 #include <toolbox/path.h>
+#include <dolphin/dolphin.h>
 
 static void ibutton_scene_save_name_text_input_callback(void* context) {
     iButton* ibutton = context;
@@ -57,6 +58,15 @@ bool ibutton_scene_save_name_on_event(void* context, SceneManagerEvent event) {
         if(event.event == iButtonCustomEventTextEditResult) {
             if(ibutton_save_key(ibutton, ibutton->text_store)) {
                 scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSaveSuccess);
+                if(scene_manager_has_previous_scene(
+                       ibutton->scene_manager, iButtonSceneSavedKeyMenu)) {
+                    // Nothing, do not count editing as saving
+                } else if(scene_manager_has_previous_scene(
+                              ibutton->scene_manager, iButtonSceneAddType)) {
+                    DOLPHIN_DEED(DolphinDeedIbuttonAdd);
+                } else {
+                    DOLPHIN_DEED(DolphinDeedIbuttonSave);
+                }
             } else {
                 const uint32_t possible_scenes[] = {
                     iButtonSceneReadKeyMenu, iButtonSceneSavedKeyMenu, iButtonSceneAddType};

+ 0 - 2
applications/main/ibutton/scenes/ibutton_scene_save_success.c

@@ -1,5 +1,4 @@
 #include "../ibutton_i.h"
-#include <dolphin/dolphin.h>
 
 static void ibutton_scene_save_success_popup_callback(void* context) {
     iButton* ibutton = context;
@@ -9,7 +8,6 @@ static void ibutton_scene_save_success_popup_callback(void* context) {
 void ibutton_scene_save_success_on_enter(void* context) {
     iButton* ibutton = context;
     Popup* popup = ibutton->popup;
-    DOLPHIN_DEED(DolphinDeedIbuttonSave);
 
     popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
     popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop);

+ 2 - 0
applications/main/ibutton/scenes/ibutton_scene_saved_key_menu.c

@@ -1,4 +1,5 @@
 #include "../ibutton_i.h"
+#include <dolphin/dolphin.h>
 
 enum SubmenuIndex {
     SubmenuIndexEmulate,
@@ -58,6 +59,7 @@ bool ibutton_scene_saved_key_menu_on_event(void* context, SceneManagerEvent even
         consumed = true;
         if(event.event == SubmenuIndexEmulate) {
             scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate);
+            DOLPHIN_DEED(DolphinDeedIbuttonEmulate);
         } else if(event.event == SubmenuIndexWrite) {
             scene_manager_next_scene(ibutton->scene_manager, iButtonSceneWrite);
         } else if(event.event == SubmenuIndexEdit) {

+ 2 - 0
applications/main/ibutton/scenes/ibutton_scene_start.c

@@ -1,5 +1,6 @@
 #include "../ibutton_i.h"
 #include "ibutton/scenes/ibutton_scene.h"
+#include <dolphin/dolphin.h>
 
 enum SubmenuIndex {
     SubmenuIndexRead,
@@ -38,6 +39,7 @@ bool ibutton_scene_start_on_event(void* context, SceneManagerEvent event) {
         consumed = true;
         if(event.event == SubmenuIndexRead) {
             scene_manager_next_scene(ibutton->scene_manager, iButtonSceneRead);
+            DOLPHIN_DEED(DolphinDeedIbuttonRead);
         } else if(event.event == SubmenuIndexSaved) {
             furi_string_set(ibutton->file_path, IBUTTON_APP_FOLDER);
             scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSelectKey);

+ 2 - 0
applications/main/infrared/scenes/infrared_scene_learn.c

@@ -1,4 +1,5 @@
 #include "../infrared_i.h"
+#include <dolphin/dolphin.h>
 
 void infrared_scene_learn_on_enter(void* context) {
     Infrared* infrared = context;
@@ -27,6 +28,7 @@ bool infrared_scene_learn_on_event(void* context, SceneManagerEvent event) {
         if(event.event == InfraredCustomEventTypeSignalReceived) {
             infrared_play_notification_message(infrared, InfraredNotificationMessageSuccess);
             scene_manager_next_scene(infrared->scene_manager, InfraredSceneLearnSuccess);
+            DOLPHIN_DEED(DolphinDeedIrLearnSuccess);
             consumed = true;
         }
     }

+ 0 - 3
applications/main/infrared/scenes/infrared_scene_learn_done.c

@@ -1,13 +1,10 @@
 #include "../infrared_i.h"
 
-#include <dolphin/dolphin.h>
-
 void infrared_scene_learn_done_on_enter(void* context) {
     Infrared* infrared = context;
     Popup* popup = infrared->popup;
 
     popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
-    DOLPHIN_DEED(DolphinDeedIrSave);
 
     if(infrared->app_state.is_learning_new_remote) {
         popup_set_header(popup, "New remote\ncreated!", 0, 0, AlignLeft, AlignTop);

+ 2 - 0
applications/main/infrared/scenes/infrared_scene_learn_enter_name.c

@@ -1,4 +1,5 @@
 #include "../infrared_i.h"
+#include <dolphin/dolphin.h>
 
 void infrared_scene_learn_enter_name_on_enter(void* context) {
     Infrared* infrared = context;
@@ -49,6 +50,7 @@ bool infrared_scene_learn_enter_name_on_event(void* context, SceneManagerEvent e
 
             if(success) {
                 scene_manager_next_scene(scene_manager, InfraredSceneLearnDone);
+                DOLPHIN_DEED(DolphinDeedIrSave);
             } else {
                 dialog_message_show_storage_error(infrared->dialogs, "Failed to save file");
                 const uint32_t possible_scenes[] = {InfraredSceneRemoteList, InfraredSceneStart};

+ 0 - 3
applications/main/infrared/scenes/infrared_scene_learn_success.c

@@ -1,7 +1,5 @@
 #include "../infrared_i.h"
 
-#include <dolphin/dolphin.h>
-
 static void
     infrared_scene_learn_success_dialog_result_callback(DialogExResult result, void* context) {
     Infrared* infrared = context;
@@ -13,7 +11,6 @@ void infrared_scene_learn_success_on_enter(void* context) {
     DialogEx* dialog_ex = infrared->dialog_ex;
     InfraredSignal* signal = infrared->received_signal;
 
-    DOLPHIN_DEED(DolphinDeedIrLearnSuccess);
     infrared_play_notification_message(infrared, InfraredNotificationMessageGreenOn);
 
     if(infrared_signal_is_raw(signal)) {

+ 4 - 1
applications/main/lfrfid/lfrfid.c

@@ -1,4 +1,5 @@
 #include "lfrfid_i.h"
+#include <dolphin/dolphin.h>
 
 static bool lfrfid_debug_custom_event_callback(void* context, uint32_t event) {
     furi_assert(context);
@@ -182,12 +183,14 @@ int32_t lfrfid_app(void* p) {
             view_dispatcher_attach_to_gui(
                 app->view_dispatcher, app->gui, ViewDispatcherTypeDesktop);
             scene_manager_next_scene(app->scene_manager, LfRfidSceneRpc);
+            DOLPHIN_DEED(DolphinDeedRfidEmulate);
         } else {
             furi_string_set(app->file_path, args);
             lfrfid_load_key_data(app, app->file_path, true);
             view_dispatcher_attach_to_gui(
                 app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
             scene_manager_next_scene(app->scene_manager, LfRfidSceneEmulate);
+            DOLPHIN_DEED(DolphinDeedRfidEmulate);
         }
 
     } else {
@@ -311,4 +314,4 @@ void lfrfid_widget_callback(GuiButtonType result, InputType type, void* context)
 void lfrfid_text_input_callback(void* context) {
     LfRfid* app = context;
     view_dispatcher_send_custom_event(app->view_dispatcher, LfRfidEventNext);
-}
+}

+ 0 - 3
applications/main/lfrfid/scenes/lfrfid_scene_emulate.c

@@ -1,12 +1,9 @@
 #include "../lfrfid_i.h"
-#include <dolphin/dolphin.h>
 
 void lfrfid_scene_emulate_on_enter(void* context) {
     LfRfid* app = context;
     Popup* popup = app->popup;
 
-    DOLPHIN_DEED(DolphinDeedRfidEmulate);
-
     popup_set_header(popup, "Emulating", 89, 30, AlignCenter, AlignTop);
     if(!furi_string_empty(app->file_name)) {
         popup_set_text(popup, furi_string_get_cstr(app->file_name), 89, 43, AlignCenter, AlignTop);

+ 3 - 0
applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c

@@ -1,4 +1,5 @@
 #include "../lfrfid_i.h"
+#include <dolphin/dolphin.h>
 
 typedef enum {
     SubmenuIndexASK,
@@ -57,10 +58,12 @@ bool lfrfid_scene_extra_actions_on_event(void* context, SceneManagerEvent event)
         if(event.event == SubmenuIndexASK) {
             app->read_type = LFRFIDWorkerReadTypeASKOnly;
             scene_manager_next_scene(app->scene_manager, LfRfidSceneRead);
+            DOLPHIN_DEED(DolphinDeedRfidRead);
             consumed = true;
         } else if(event.event == SubmenuIndexPSK) {
             app->read_type = LFRFIDWorkerReadTypePSKOnly;
             scene_manager_next_scene(app->scene_manager, LfRfidSceneRead);
+            DOLPHIN_DEED(DolphinDeedRfidRead);
             consumed = true;
         } else if(event.event == SubmenuIndexRAW) {
             scene_manager_next_scene(app->scene_manager, LfRfidSceneRawName);

+ 1 - 2
applications/main/lfrfid/scenes/lfrfid_scene_read.c

@@ -46,7 +46,6 @@ static void
 void lfrfid_scene_read_on_enter(void* context) {
     LfRfid* app = context;
 
-    DOLPHIN_DEED(DolphinDeedRfidRead);
     if(app->read_type == LFRFIDWorkerReadTypePSKOnly) {
         lfrfid_view_read_set_read_mode(app->read_view, LfRfidReadPskOnly);
     } else if(app->read_type == LFRFIDWorkerReadTypeASKOnly) {
@@ -79,10 +78,10 @@ bool lfrfid_scene_read_on_event(void* context, SceneManagerEvent event) {
             consumed = true;
         } else if(event.event == LfRfidEventReadDone) {
             app->protocol_id = app->protocol_id_next;
-            DOLPHIN_DEED(DolphinDeedRfidReadSuccess);
             notification_message(app->notifications, &sequence_success);
             furi_string_reset(app->file_name);
             scene_manager_next_scene(app->scene_manager, LfRfidSceneReadSuccess);
+            DOLPHIN_DEED(DolphinDeedRfidReadSuccess);
             consumed = true;
         } else if(event.event == LfRfidEventReadStartPSK) {
             if(app->read_type == LFRFIDWorkerReadTypeAuto) {

+ 2 - 0
applications/main/lfrfid/scenes/lfrfid_scene_read_key_menu.c

@@ -1,4 +1,5 @@
 #include "../lfrfid_i.h"
+#include <dolphin/dolphin.h>
 
 typedef enum {
     SubmenuIndexSave,
@@ -43,6 +44,7 @@ bool lfrfid_scene_read_key_menu_on_event(void* context, SceneManagerEvent event)
             consumed = true;
         } else if(event.event == SubmenuIndexEmulate) {
             scene_manager_next_scene(app->scene_manager, LfRfidSceneEmulate);
+            DOLPHIN_DEED(DolphinDeedRfidEmulate);
             consumed = true;
         }
         scene_manager_set_scene_state(app->scene_manager, LfRfidSceneReadKeyMenu, event.event);

+ 0 - 2
applications/main/lfrfid/scenes/lfrfid_scene_save_data.c

@@ -1,5 +1,4 @@
 #include "../lfrfid_i.h"
-#include <dolphin/dolphin.h>
 
 void lfrfid_scene_save_data_on_enter(void* context) {
     LfRfid* app = context;
@@ -32,7 +31,6 @@ bool lfrfid_scene_save_data_on_event(void* context, SceneManagerEvent event) {
             consumed = true;
             size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id);
             protocol_dict_set_data(app->dict, app->protocol_id, app->new_key_data, size);
-            DOLPHIN_DEED(DolphinDeedRfidAdd);
             scene_manager_next_scene(scene_manager, LfRfidSceneSaveName);
             scene_manager_set_scene_state(scene_manager, LfRfidSceneSaveData, 1);
         }

+ 8 - 0
applications/main/lfrfid/scenes/lfrfid_scene_save_name.c

@@ -1,5 +1,6 @@
 #include <lib/toolbox/random_name.h>
 #include "../lfrfid_i.h"
+#include <dolphin/dolphin.h>
 
 void lfrfid_scene_save_name_on_enter(void* context) {
     LfRfid* app = context;
@@ -55,6 +56,13 @@ bool lfrfid_scene_save_name_on_event(void* context, SceneManagerEvent event) {
 
             if(lfrfid_save_key(app)) {
                 scene_manager_next_scene(scene_manager, LfRfidSceneSaveSuccess);
+                if(scene_manager_has_previous_scene(scene_manager, LfRfidSceneSavedKeyMenu)) {
+                    // Nothing, do not count editing as saving
+                } else if(scene_manager_has_previous_scene(scene_manager, LfRfidSceneSaveType)) {
+                    DOLPHIN_DEED(DolphinDeedRfidAdd);
+                } else {
+                    DOLPHIN_DEED(DolphinDeedRfidSave);
+                }
             } else {
                 scene_manager_search_and_switch_to_previous_scene(
                     scene_manager, LfRfidSceneReadKeyMenu);

+ 0 - 2
applications/main/lfrfid/scenes/lfrfid_scene_save_success.c

@@ -1,5 +1,4 @@
 #include "../lfrfid_i.h"
-#include <dolphin/dolphin.h>
 
 void lfrfid_scene_save_success_on_enter(void* context) {
     LfRfid* app = context;
@@ -8,7 +7,6 @@ void lfrfid_scene_save_success_on_enter(void* context) {
     // Clear state of data enter scene
     scene_manager_set_scene_state(app->scene_manager, LfRfidSceneSaveData, 0);
 
-    DOLPHIN_DEED(DolphinDeedRfidSave);
     popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
     popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop);
     popup_set_context(popup, app);

+ 2 - 0
applications/main/lfrfid/scenes/lfrfid_scene_saved_key_menu.c

@@ -1,4 +1,5 @@
 #include "../lfrfid_i.h"
+#include <dolphin/dolphin.h>
 
 typedef enum {
     SubmenuIndexEmulate,
@@ -42,6 +43,7 @@ bool lfrfid_scene_saved_key_menu_on_event(void* context, SceneManagerEvent event
     if(event.type == SceneManagerEventTypeCustom) {
         if(event.event == SubmenuIndexEmulate) {
             scene_manager_next_scene(app->scene_manager, LfRfidSceneEmulate);
+            DOLPHIN_DEED(DolphinDeedRfidEmulate);
             consumed = true;
         } else if(event.event == SubmenuIndexWrite) {
             scene_manager_next_scene(app->scene_manager, LfRfidSceneWrite);

+ 2 - 0
applications/main/lfrfid/scenes/lfrfid_scene_start.c

@@ -1,4 +1,5 @@
 #include "../lfrfid_i.h"
+#include <dolphin/dolphin.h>
 
 typedef enum {
     SubmenuIndexRead,
@@ -47,6 +48,7 @@ bool lfrfid_scene_start_on_event(void* context, SceneManagerEvent event) {
     if(event.type == SceneManagerEventTypeCustom) {
         if(event.event == SubmenuIndexRead) {
             scene_manager_next_scene(app->scene_manager, LfRfidSceneRead);
+            DOLPHIN_DEED(DolphinDeedRfidRead);
             consumed = true;
         } else if(event.event == SubmenuIndexSaved) {
             furi_string_set(app->file_path, LFRFID_APP_FOLDER);

+ 4 - 0
applications/main/nfc/nfc.c

@@ -1,5 +1,6 @@
 #include "nfc_i.h"
 #include "furi_hal_nfc.h"
+#include <dolphin/dolphin.h>
 
 bool nfc_custom_event_callback(void* context, uint32_t event) {
     furi_assert(context);
@@ -275,12 +276,15 @@ int32_t nfc_app(void* p) {
             if(nfc_device_load(nfc->dev, p, true)) {
                 if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) {
                     scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightEmulate);
+                    DOLPHIN_DEED(DolphinDeedNfcEmulate);
                 } else if(nfc->dev->format == NfcDeviceSaveFormatMifareClassic) {
                     scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicEmulate);
+                    DOLPHIN_DEED(DolphinDeedNfcEmulate);
                 } else if(nfc->dev->format == NfcDeviceSaveFormatBankCard) {
                     scene_manager_next_scene(nfc->scene_manager, NfcSceneDeviceInfo);
                 } else {
                     scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid);
+                    DOLPHIN_DEED(DolphinDeedNfcEmulate);
                 }
             } else {
                 // Exit app

+ 0 - 2
applications/main/nfc/scenes/nfc_scene_detect_reader.c

@@ -1,5 +1,4 @@
 #include "../nfc_i.h"
-#include <dolphin/dolphin.h>
 
 #define NFC_SCENE_DETECT_READER_PAIR_NONCES_MAX (10U)
 
@@ -26,7 +25,6 @@ void nfc_scene_detect_reader_callback(void* context) {
 
 void nfc_scene_detect_reader_on_enter(void* context) {
     Nfc* nfc = context;
-    DOLPHIN_DEED(DolphinDeedNfcDetectReader);
 
     detect_reader_set_callback(nfc->detect_reader, nfc_scene_detect_reader_callback, nfc);
     detect_reader_set_nonces_max(nfc->detect_reader, NFC_SCENE_DETECT_READER_PAIR_NONCES_MAX);

+ 0 - 2
applications/main/nfc/scenes/nfc_scene_emulate_uid.c

@@ -1,5 +1,4 @@
 #include "../nfc_i.h"
-#include <dolphin/dolphin.h>
 
 #define NFC_SCENE_EMULATE_UID_LOG_SIZE_MAX (200)
 
@@ -59,7 +58,6 @@ static void nfc_scene_emulate_uid_widget_config(Nfc* nfc, bool data_received) {
 
 void nfc_scene_emulate_uid_on_enter(void* context) {
     Nfc* nfc = context;
-    DOLPHIN_DEED(DolphinDeedNfcEmulate);
 
     // Setup Widget
     nfc_scene_emulate_uid_widget_config(nfc, false);

+ 0 - 2
applications/main/nfc/scenes/nfc_scene_emv_read_success.c

@@ -1,6 +1,5 @@
 #include "../nfc_i.h"
 #include "../helpers/nfc_emv_parser.h"
-#include <dolphin/dolphin.h>
 
 void nfc_scene_emv_read_success_widget_callback(
     GuiButtonType result,
@@ -15,7 +14,6 @@ void nfc_scene_emv_read_success_widget_callback(
 void nfc_scene_emv_read_success_on_enter(void* context) {
     Nfc* nfc = context;
     EmvData* emv_data = &nfc->dev->dev_data.emv_data;
-    DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
 
     // Setup Custom Widget view
     widget_add_button_element(

+ 4 - 0
applications/main/nfc/scenes/nfc_scene_mf_classic_dict_attack.c

@@ -1,4 +1,5 @@
 #include "../nfc_i.h"
+#include <dolphin/dolphin.h>
 
 #define TAG "NfcMfClassicDictAttack"
 
@@ -110,6 +111,7 @@ bool nfc_scene_mf_classic_dict_attack_on_event(void* context, SceneManagerEvent
             } else {
                 notification_message(nfc->notifications, &sequence_success);
                 scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicReadSuccess);
+                DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
                 consumed = true;
             }
         } else if(event.event == NfcWorkerEventAborted) {
@@ -119,6 +121,8 @@ bool nfc_scene_mf_classic_dict_attack_on_event(void* context, SceneManagerEvent
             } else {
                 notification_message(nfc->notifications, &sequence_success);
                 scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicReadSuccess);
+                // Counting failed attempts too
+                DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
                 consumed = true;
             }
         } else if(event.event == NfcWorkerEventCardDetected) {

+ 0 - 2
applications/main/nfc/scenes/nfc_scene_mf_classic_emulate.c

@@ -1,5 +1,4 @@
 #include "../nfc_i.h"
-#include <dolphin/dolphin.h>
 
 #define NFC_MF_CLASSIC_DATA_NOT_CHANGED (0UL)
 #define NFC_MF_CLASSIC_DATA_CHANGED (1UL)
@@ -15,7 +14,6 @@ bool nfc_mf_classic_emulate_worker_callback(NfcWorkerEvent event, void* context)
 
 void nfc_scene_mf_classic_emulate_on_enter(void* context) {
     Nfc* nfc = context;
-    DOLPHIN_DEED(DolphinDeedNfcEmulate);
 
     // Setup view
     Popup* popup = nfc->popup;

+ 2 - 0
applications/main/nfc/scenes/nfc_scene_mf_classic_keys_add.c

@@ -1,4 +1,5 @@
 #include "../nfc_i.h"
+#include <dolphin/dolphin.h>
 
 void nfc_scene_mf_classic_keys_add_byte_input_callback(void* context) {
     Nfc* nfc = context;
@@ -36,6 +37,7 @@ bool nfc_scene_mf_classic_keys_add_on_event(void* context, SceneManagerEvent eve
                         nfc->scene_manager, NfcSceneMfClassicKeysWarnDuplicate);
                 } else if(mf_classic_dict_add_key(dict, nfc->byte_input_store)) {
                     scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveSuccess);
+                    DOLPHIN_DEED(DolphinDeedNfcMfcAdd);
                 } else {
                     scene_manager_next_scene(nfc->scene_manager, NfcSceneDictNotFound);
                 }

+ 5 - 2
applications/main/nfc/scenes/nfc_scene_mf_classic_menu.c

@@ -36,8 +36,6 @@ bool nfc_scene_mf_classic_menu_on_event(void* context, SceneManagerEvent event)
 
     if(event.type == SceneManagerEventTypeCustom) {
         if(event.event == SubmenuIndexSave) {
-            DOLPHIN_DEED(DolphinDeedNfcMfcAdd);
-
             scene_manager_set_scene_state(
                 nfc->scene_manager, NfcSceneMfClassicMenu, SubmenuIndexSave);
             nfc->dev->format = NfcDeviceSaveFormatMifareClassic;
@@ -49,6 +47,11 @@ bool nfc_scene_mf_classic_menu_on_event(void* context, SceneManagerEvent event)
             scene_manager_set_scene_state(
                 nfc->scene_manager, NfcSceneMfClassicMenu, SubmenuIndexEmulate);
             scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicEmulate);
+            if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSetType)) {
+                DOLPHIN_DEED(DolphinDeedNfcAddEmulate);
+            } else {
+                DOLPHIN_DEED(DolphinDeedNfcEmulate);
+            }
             consumed = true;
         } else if(event.event == SubmenuIndexInfo) {
             scene_manager_set_scene_state(

+ 0 - 3
applications/main/nfc/scenes/nfc_scene_mf_classic_read_success.c

@@ -1,5 +1,4 @@
 #include "../nfc_i.h"
-#include <dolphin/dolphin.h>
 
 void nfc_scene_mf_classic_read_success_widget_callback(
     GuiButtonType result,
@@ -18,8 +17,6 @@ void nfc_scene_mf_classic_read_success_on_enter(void* context) {
     NfcDeviceData* dev_data = &nfc->dev->dev_data;
     MfClassicData* mf_data = &dev_data->mf_classic_data;
 
-    DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
-
     // Setup view
     Widget* widget = nfc->widget;
     widget_add_button_element(

+ 6 - 0
applications/main/nfc/scenes/nfc_scene_mf_desfire_menu.c

@@ -1,4 +1,5 @@
 #include "../nfc_i.h"
+#include <dolphin/dolphin.h>
 
 enum SubmenuIndex {
     SubmenuIndexSave,
@@ -48,6 +49,11 @@ bool nfc_scene_mf_desfire_menu_on_event(void* context, SceneManagerEvent event)
             consumed = true;
         } else if(event.event == SubmenuIndexEmulateUid) {
             scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid);
+            if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSetType)) {
+                DOLPHIN_DEED(DolphinDeedNfcAddEmulate);
+            } else {
+                DOLPHIN_DEED(DolphinDeedNfcEmulate);
+            }
             consumed = true;
         } else if(event.event == SubmenuIndexInfo) {
             scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcDataInfo);

+ 0 - 2
applications/main/nfc/scenes/nfc_scene_mf_ultralight_emulate.c

@@ -1,5 +1,4 @@
 #include "../nfc_i.h"
-#include <dolphin/dolphin.h>
 
 #define NFC_MF_UL_DATA_NOT_CHANGED (0UL)
 #define NFC_MF_UL_DATA_CHANGED (1UL)
@@ -15,7 +14,6 @@ bool nfc_mf_ultralight_emulate_worker_callback(NfcWorkerEvent event, void* conte
 
 void nfc_scene_mf_ultralight_emulate_on_enter(void* context) {
     Nfc* nfc = context;
-    DOLPHIN_DEED(DolphinDeedNfcEmulate);
 
     // Setup view
     Popup* popup = nfc->popup;

+ 6 - 0
applications/main/nfc/scenes/nfc_scene_mf_ultralight_menu.c

@@ -1,4 +1,5 @@
 #include "../nfc_i.h"
+#include <dolphin/dolphin.h>
 
 enum SubmenuIndex {
     SubmenuIndexUnlock,
@@ -56,6 +57,11 @@ bool nfc_scene_mf_ultralight_menu_on_event(void* context, SceneManagerEvent even
             consumed = true;
         } else if(event.event == SubmenuIndexEmulate) {
             scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightEmulate);
+            if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSetType)) {
+                DOLPHIN_DEED(DolphinDeedNfcAddEmulate);
+            } else {
+                DOLPHIN_DEED(DolphinDeedNfcEmulate);
+            }
             consumed = true;
         } else if(event.event == SubmenuIndexUnlock) {
             scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightUnlockMenu);

+ 0 - 2
applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_auth.c

@@ -1,5 +1,4 @@
 #include "../nfc_i.h"
-#include <dolphin/dolphin.h>
 
 typedef enum {
     NfcSceneMfUlReadStateIdle,
@@ -51,7 +50,6 @@ void nfc_scene_mf_ultralight_read_auth_set_state(Nfc* nfc, NfcSceneMfUlReadState
 
 void nfc_scene_mf_ultralight_read_auth_on_enter(void* context) {
     Nfc* nfc = context;
-    DOLPHIN_DEED(DolphinDeedNfcRead);
 
     nfc_device_clear(nfc->dev);
     // Setup view

+ 0 - 4
applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_auth_result.c

@@ -1,5 +1,4 @@
 #include "../nfc_i.h"
-#include <dolphin/dolphin.h>
 
 void nfc_scene_mf_ultralight_read_auth_result_widget_callback(
     GuiButtonType result,
@@ -37,7 +36,6 @@ void nfc_scene_mf_ultralight_read_auth_result_on_enter(void* context) {
     widget_add_string_element(
         widget, 0, 17, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(temp_str));
     if(mf_ul_data->auth_success) {
-        DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
         furi_string_printf(
             temp_str,
             "Password: %02X %02X %02X %02X",
@@ -54,8 +52,6 @@ void nfc_scene_mf_ultralight_read_auth_result_on_enter(void* context) {
             config_pages->auth_data.pack.raw[1]);
         widget_add_string_element(
             widget, 0, 39, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(temp_str));
-    } else {
-        DOLPHIN_DEED(DolphinDeedNfcMfulError);
     }
     furi_string_printf(
         temp_str, "Pages Read: %d/%d", mf_ul_data->data_read / 4, mf_ul_data->data_size / 4);

+ 0 - 2
applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_success.c

@@ -1,5 +1,4 @@
 #include "../nfc_i.h"
-#include <dolphin/dolphin.h>
 
 void nfc_scene_mf_ultralight_read_success_widget_callback(
     GuiButtonType result,
@@ -14,7 +13,6 @@ void nfc_scene_mf_ultralight_read_success_widget_callback(
 
 void nfc_scene_mf_ultralight_read_success_on_enter(void* context) {
     Nfc* nfc = context;
-    DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
 
     // Setup widget view
     FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data;

+ 2 - 0
applications/main/nfc/scenes/nfc_scene_mf_ultralight_unlock_warn.c

@@ -1,4 +1,5 @@
 #include "../nfc_i.h"
+#include <dolphin/dolphin.h>
 
 void nfc_scene_mf_ultralight_unlock_warn_dialog_callback(DialogExResult result, void* context) {
     Nfc* nfc = context;
@@ -30,6 +31,7 @@ bool nfc_scene_mf_ultralight_unlock_warn_on_event(void* context, SceneManagerEve
     if(event.type == SceneManagerEventTypeCustom) {
         if(event.event == DialogExResultCenter) {
             scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightReadAuth);
+            DOLPHIN_DEED(DolphinDeedNfcRead);
             consumed = true;
         }
     }

+ 6 - 0
applications/main/nfc/scenes/nfc_scene_nfca_menu.c

@@ -1,4 +1,5 @@
 #include "../nfc_i.h"
+#include <dolphin/dolphin.h>
 
 enum SubmenuIndex {
     SubmenuIndexSaveUid,
@@ -41,6 +42,11 @@ bool nfc_scene_nfca_menu_on_event(void* context, SceneManagerEvent event) {
             consumed = true;
         } else if(event.event == SubmenuIndexEmulateUid) {
             scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid);
+            if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSetType)) {
+                DOLPHIN_DEED(DolphinDeedNfcAddEmulate);
+            } else {
+                DOLPHIN_DEED(DolphinDeedNfcEmulate);
+            }
             consumed = true;
         } else if(event.event == SubmenuIndexInfo) {
             scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcDataInfo);

+ 0 - 3
applications/main/nfc/scenes/nfc_scene_nfca_read_success.c

@@ -1,5 +1,4 @@
 #include "../nfc_i.h"
-#include <dolphin/dolphin.h>
 
 void nfc_scene_nfca_read_success_widget_callback(
     GuiButtonType result,
@@ -16,8 +15,6 @@ void nfc_scene_nfca_read_success_widget_callback(
 void nfc_scene_nfca_read_success_on_enter(void* context) {
     Nfc* nfc = context;
 
-    DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
-
     // Setup view
     FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data;
     Widget* widget = nfc->widget;

+ 6 - 1
applications/main/nfc/scenes/nfc_scene_read.c

@@ -39,7 +39,6 @@ void nfc_scene_read_set_state(Nfc* nfc, NfcSceneReadState state) {
 
 void nfc_scene_read_on_enter(void* context) {
     Nfc* nfc = context;
-    DOLPHIN_DEED(DolphinDeedNfcRead);
 
     nfc_device_clear(nfc->dev);
     // Setup view
@@ -62,26 +61,32 @@ bool nfc_scene_read_on_event(void* context, SceneManagerEvent event) {
            (event.event == NfcWorkerEventReadUidNfcV)) {
             notification_message(nfc->notifications, &sequence_success);
             scene_manager_next_scene(nfc->scene_manager, NfcSceneReadCardSuccess);
+            DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
             consumed = true;
         } else if(event.event == NfcWorkerEventReadUidNfcA) {
             notification_message(nfc->notifications, &sequence_success);
             scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcaReadSuccess);
+            DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
             consumed = true;
         } else if(event.event == NfcWorkerEventReadMfUltralight) {
             notification_message(nfc->notifications, &sequence_success);
             scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightReadSuccess);
+            DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
             consumed = true;
         } else if(event.event == NfcWorkerEventReadMfClassicDone) {
             notification_message(nfc->notifications, &sequence_success);
             scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicReadSuccess);
+            DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
             consumed = true;
         } else if(event.event == NfcWorkerEventReadMfDesfire) {
             notification_message(nfc->notifications, &sequence_success);
             scene_manager_next_scene(nfc->scene_manager, NfcSceneMfDesfireReadSuccess);
+            DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
             consumed = true;
         } else if(event.event == NfcWorkerEventReadBankCard) {
             notification_message(nfc->notifications, &sequence_success);
             scene_manager_next_scene(nfc->scene_manager, NfcSceneEmvReadSuccess);
+            DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
             consumed = true;
         } else if(event.event == NfcWorkerEventReadMfClassicDictAttackRequired) {
             if(mf_classic_dict_check_presence(MfClassicDictTypeFlipper)) {

+ 0 - 2
applications/main/nfc/scenes/nfc_scene_read_card_success.c

@@ -1,5 +1,4 @@
 #include "../nfc_i.h"
-#include <dolphin/dolphin.h>
 
 void nfc_scene_read_card_success_widget_callback(
     GuiButtonType result,
@@ -18,7 +17,6 @@ void nfc_scene_read_card_success_on_enter(void* context) {
 
     FuriString* temp_str;
     temp_str = furi_string_alloc();
-    DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
 
     // Setup view
     FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data;

+ 8 - 0
applications/main/nfc/scenes/nfc_scene_save_name.c

@@ -2,6 +2,7 @@
 #include <lib/toolbox/random_name.h>
 #include <gui/modules/validators.h>
 #include <toolbox/path.h>
+#include <dolphin/dolphin.h>
 
 void nfc_scene_save_name_text_input_callback(void* context) {
     Nfc* nfc = context;
@@ -63,6 +64,13 @@ bool nfc_scene_save_name_on_event(void* context, SceneManagerEvent event) {
             strlcpy(nfc->dev->dev_name, nfc->text_store, strlen(nfc->text_store) + 1);
             if(nfc_device_save(nfc->dev, nfc->text_store)) {
                 scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveSuccess);
+                if(!scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSavedMenu)) {
+                    // Nothing, do not count editing as saving
+                } else if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSetType)) {
+                    DOLPHIN_DEED(DolphinDeedNfcAddSave);
+                } else {
+                    DOLPHIN_DEED(DolphinDeedNfcSave);
+                }
                 consumed = true;
             } else {
                 consumed = scene_manager_search_and_switch_to_previous_scene(

+ 0 - 2
applications/main/nfc/scenes/nfc_scene_save_success.c

@@ -1,5 +1,4 @@
 #include "../nfc_i.h"
-#include <dolphin/dolphin.h>
 
 void nfc_scene_save_success_popup_callback(void* context) {
     Nfc* nfc = context;
@@ -8,7 +7,6 @@ void nfc_scene_save_success_popup_callback(void* context) {
 
 void nfc_scene_save_success_on_enter(void* context) {
     Nfc* nfc = context;
-    DOLPHIN_DEED(DolphinDeedNfcSave);
 
     // Setup view
     Popup* popup = nfc->popup;

+ 2 - 0
applications/main/nfc/scenes/nfc_scene_saved_menu.c

@@ -1,4 +1,5 @@
 #include "../nfc_i.h"
+#include <dolphin/dolphin.h>
 
 enum SubmenuIndex {
     SubmenuIndexEmulate,
@@ -76,6 +77,7 @@ bool nfc_scene_saved_menu_on_event(void* context, SceneManagerEvent event) {
             } else {
                 scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid);
             }
+            DOLPHIN_DEED(DolphinDeedNfcEmulate);
             consumed = true;
         } else if(event.event == SubmenuIndexRename) {
             scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName);

+ 0 - 2
applications/main/nfc/scenes/nfc_scene_set_uid.c

@@ -1,5 +1,4 @@
 #include "../nfc_i.h"
-#include <dolphin/dolphin.h>
 
 void nfc_scene_set_uid_byte_input_callback(void* context) {
     Nfc* nfc = context;
@@ -30,7 +29,6 @@ bool nfc_scene_set_uid_on_event(void* context, SceneManagerEvent event) {
 
     if(event.type == SceneManagerEventTypeCustom) {
         if(event.event == NfcCustomEventByteInputDone) {
-            DOLPHIN_DEED(DolphinDeedNfcAddSave);
             if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSavedMenu)) {
                 nfc->dev->dev_data.nfc_data = nfc->dev_edit_data;
                 if(nfc_device_save(nfc->dev, nfc->dev->dev_name)) {

+ 3 - 0
applications/main/nfc/scenes/nfc_scene_start.c

@@ -1,4 +1,5 @@
 #include "../nfc_i.h"
+#include <dolphin/dolphin.h>
 
 enum SubmenuIndex {
     SubmenuIndexRead,
@@ -47,11 +48,13 @@ bool nfc_scene_start_on_event(void* context, SceneManagerEvent event) {
     if(event.type == SceneManagerEventTypeCustom) {
         if(event.event == SubmenuIndexRead) {
             scene_manager_next_scene(nfc->scene_manager, NfcSceneRead);
+            DOLPHIN_DEED(DolphinDeedNfcRead);
             consumed = true;
         } else if(event.event == SubmenuIndexDetectReader) {
             bool sd_exist = storage_sd_status(nfc->dev->storage) == FSE_OK;
             if(sd_exist) {
                 scene_manager_next_scene(nfc->scene_manager, NfcSceneDetectReader);
+                DOLPHIN_DEED(DolphinDeedNfcDetectReader);
             } else {
                 scene_manager_next_scene(nfc->scene_manager, NfcSceneDictNotFound);
             }

+ 0 - 2
applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c

@@ -1,6 +1,5 @@
 #include "../subghz_i.h"
 #include "../views/subghz_frequency_analyzer.h"
-#include <dolphin/dolphin.h>
 
 void subghz_scene_frequency_analyzer_callback(SubGhzCustomEvent event, void* context) {
     furi_assert(context);
@@ -10,7 +9,6 @@ void subghz_scene_frequency_analyzer_callback(SubGhzCustomEvent event, void* con
 
 void subghz_scene_frequency_analyzer_on_enter(void* context) {
     SubGhz* subghz = context;
-    DOLPHIN_DEED(DolphinDeedSubGhzFrequencyAnalyzer);
     subghz_frequency_analyzer_set_callback(
         subghz->subghz_frequency_analyzer, subghz_scene_frequency_analyzer_callback, subghz);
     view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdFrequencyAnalyzer);

+ 6 - 1
applications/main/subghz/scenes/subghz_scene_read_raw.c

@@ -223,7 +223,12 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
                         subghz->txrx->rx_key_state = SubGhzRxKeyStateBack;
                         scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx);
                     } else {
-                        DOLPHIN_DEED(DolphinDeedSubGhzSend);
+                        if(scene_manager_has_previous_scene(
+                               subghz->scene_manager, SubGhzSceneSaved) ||
+                           !scene_manager_has_previous_scene(
+                               subghz->scene_manager, SubGhzSceneStart)) {
+                            DOLPHIN_DEED(DolphinDeedSubGhzSend);
+                        }
                         // set callback end tx
                         subghz_protocol_raw_file_encoder_worker_set_callback_end(
                             (SubGhzProtocolEncoderRAW*)subghz_transmitter_get_protocol_instance(

+ 2 - 0
applications/main/subghz/scenes/subghz_scene_receiver.c

@@ -1,5 +1,6 @@
 #include "../subghz_i.h"
 #include "../views/receiver.h"
+#include <dolphin/dolphin.h>
 
 static const NotificationSequence subghs_sequence_rx = {
     &message_green_255,
@@ -181,6 +182,7 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) {
             subghz->txrx->idx_menu_chosen =
                 subghz_view_receiver_get_idx_menu(subghz->subghz_receiver);
             scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiverInfo);
+            DOLPHIN_DEED(DolphinDeedSubGhzReceiverInfo);
             consumed = true;
             break;
         case SubGhzCustomEventViewReceiverConfig:

+ 0 - 2
applications/main/subghz/scenes/subghz_scene_receiver_info.c

@@ -1,6 +1,5 @@
 #include "../subghz_i.h"
 #include "../helpers/subghz_custom_event.h"
-#include <dolphin/dolphin.h>
 
 void subghz_scene_receiver_info_callback(GuiButtonType result, InputType type, void* context) {
     furi_assert(context);
@@ -45,7 +44,6 @@ static bool subghz_scene_receiver_info_update_parser(void* context) {
 void subghz_scene_receiver_info_on_enter(void* context) {
     SubGhz* subghz = context;
 
-    DOLPHIN_DEED(DolphinDeedSubGhzReceiverInfo);
     if(subghz_scene_receiver_info_update_parser(subghz)) {
         FuriString* frequency_str;
         FuriString* modulation_str;

+ 12 - 0
applications/main/subghz/scenes/subghz_scene_save_name.c

@@ -4,6 +4,7 @@
 #include "../helpers/subghz_custom_event.h"
 #include <lib/subghz/protocols/raw.h>
 #include <gui/modules/validators.h>
+#include <dolphin/dolphin.h>
 
 #define MAX_TEXT_INPUT_LEN 22
 
@@ -131,6 +132,17 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) {
                 }
 
                 scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveSuccess);
+                if(scene_manager_has_previous_scene(subghz->scene_manager, SubGhzSceneSavedMenu)) {
+                    // Nothing, do not count editing as saving
+                } else if(scene_manager_has_previous_scene(
+                              subghz->scene_manager, SubGhzSceneMoreRAW)) {
+                    // Ditto, for RAW signals
+                } else if(scene_manager_has_previous_scene(
+                              subghz->scene_manager, SubGhzSceneSetType)) {
+                    DOLPHIN_DEED(DolphinDeedSubGhzAddManually);
+                } else {
+                    DOLPHIN_DEED(DolphinDeedSubGhzSave);
+                }
                 return true;
             } else {
                 furi_string_set(subghz->error_str, "No name file");

+ 0 - 3
applications/main/subghz/scenes/subghz_scene_save_success.c

@@ -1,7 +1,5 @@
 #include "../subghz_i.h"
 #include "../helpers/subghz_custom_event.h"
-#include <dolphin/helpers/dolphin_deed.h>
-#include <dolphin/dolphin.h>
 
 void subghz_scene_save_success_popup_callback(void* context) {
     SubGhz* subghz = context;
@@ -10,7 +8,6 @@ void subghz_scene_save_success_popup_callback(void* context) {
 
 void subghz_scene_save_success_on_enter(void* context) {
     SubGhz* subghz = context;
-    DOLPHIN_DEED(DolphinDeedSubGhzSave);
 
     // Setup view
     Popup* popup = subghz->popup;

+ 0 - 2
applications/main/subghz/scenes/subghz_scene_set_type.c

@@ -3,7 +3,6 @@
 #include <lib/subghz/protocols/secplus_v1.h>
 #include <lib/subghz/protocols/secplus_v2.h>
 #include <lib/subghz/blocks/math.h>
-#include <dolphin/dolphin.h>
 #include <flipper_format/flipper_format_i.h>
 #include <lib/toolbox/stream/stream.h>
 #include <lib/subghz/protocols/protocol_items.h>
@@ -381,7 +380,6 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
 
         if(generated_protocol) {
             subghz_file_name_clear(subghz);
-            DOLPHIN_DEED(DolphinDeedSubGhzAddManually);
             scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName);
             return true;
         }

+ 2 - 0
applications/main/subghz/scenes/subghz_scene_start.c

@@ -1,4 +1,5 @@
 #include "../subghz_i.h"
+#include <dolphin/dolphin.h>
 
 enum SubmenuIndex {
     SubmenuIndexRead = 10,
@@ -84,6 +85,7 @@ bool subghz_scene_start_on_event(void* context, SceneManagerEvent event) {
             scene_manager_set_scene_state(
                 subghz->scene_manager, SubGhzSceneStart, SubmenuIndexFrequencyAnalyzer);
             scene_manager_next_scene(subghz->scene_manager, SubGhzSceneFrequencyAnalyzer);
+            DOLPHIN_DEED(DolphinDeedSubGhzFrequencyAnalyzer);
             return true;
         } else if(event.event == SubmenuIndexTest) {
             scene_manager_set_scene_state(

+ 1 - 1
applications/main/subghz/scenes/subghz_scene_transmitter.c

@@ -50,7 +50,6 @@ bool subghz_scene_transmitter_update_data_show(void* context) {
 
 void subghz_scene_transmitter_on_enter(void* context) {
     SubGhz* subghz = context;
-    DOLPHIN_DEED(DolphinDeedSubGhzSend);
     if(!subghz_scene_transmitter_update_data_show(subghz)) {
         view_dispatcher_send_custom_event(
             subghz->view_dispatcher, SubGhzCustomEventViewTransmitterError);
@@ -78,6 +77,7 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) {
                 } else {
                     subghz->state_notifications = SubGhzNotificationStateTx;
                     subghz_scene_transmitter_update_data_show(subghz);
+                    DOLPHIN_DEED(DolphinDeedSubGhzSend);
                 }
             }
             return true;

+ 1 - 1
applications/services/dolphin/helpers/dolphin_deed.c

@@ -21,8 +21,8 @@ static const DolphinDeedWeight dolphin_deed_weights[] = {
     {1, DolphinAppNfc}, // DolphinDeedNfcDetectReader
     {2, DolphinAppNfc}, // DolphinDeedNfcEmulate
     {2, DolphinAppNfc}, // DolphinDeedNfcMfcAdd
-    {1, DolphinAppNfc}, // DolphinDeedNfcMfulError
     {1, DolphinAppNfc}, // DolphinDeedNfcAddSave
+    {1, DolphinAppNfc}, // DolphinDeedNfcAddEmulate
 
     {1, DolphinAppIr}, // DolphinDeedIrSend
     {3, DolphinAppIr}, // DolphinDeedIrLearnSuccess

+ 1 - 1
applications/services/dolphin/helpers/dolphin_deed.h

@@ -37,8 +37,8 @@ typedef enum {
     DolphinDeedNfcDetectReader,
     DolphinDeedNfcEmulate,
     DolphinDeedNfcMfcAdd,
-    DolphinDeedNfcMfulError,
     DolphinDeedNfcAddSave,
+    DolphinDeedNfcAddEmulate,
 
     DolphinDeedIrSend,
     DolphinDeedIrLearnSuccess,