wzx 2 лет назад
Родитель
Сommit
fed96e8e5f
100 измененных файлов с 4033 добавлено и 8832 удалено
  1. BIN
      assets/images/common/page_bg_dark.png
  2. BIN
      assets/images/ic_flag_blue.png
  3. BIN
      assets/images/ic_flag_red.png
  4. BIN
      assets/images/ic_flag_yellow.png
  5. BIN
      assets/images/ic_radio_selected_gray.png
  6. BIN
      assets/images/ic_radio_selected_orange.png
  7. 1132 0
      lib/generated/to_app_api.pb.dart
  8. 11 0
      lib/generated/to_app_api.pbenum.dart
  9. 240 0
      lib/generated/to_app_api.pbgrpc.dart
  10. 305 0
      lib/generated/to_app_api.pbjson.dart
  11. 0 0
      lib/model/__game_person_data.dart.bk
  12. 0 0
      lib/model/__project.dart.bk
  13. 0 0
      lib/model/__provider.dart.bk
  14. 0 0
      lib/model/__settlement.dart.bk
  15. 22 22
      lib/model/game_state.dart
  16. 659 0
      lib/service/api.dart.bk
  17. 1 1
      lib/service/game/game.dart.bk
  18. 0 0
      lib/service/game/game_instance_guardian.dart.bk
  19. 1 1
      lib/service/game/game_instance_std/game_instance_std.dart.bk
  20. 0 0
      lib/service/game/game_instance_std/plug_location.dart.bk
  21. 0 0
      lib/service/game/game_instance_std/plug_orientation.dart.bk
  22. 0 0
      lib/service/game/game_instance_std/plug_sport_wear.dart.bk
  23. 0 0
      lib/service/game/game_manager_service.dart.bk
  24. 1 1
      lib/service/game/map_status.dart.bk
  25. 0 0
      lib/service/game/plug_location.dart.bk
  26. 0 0
      lib/service/game/plug_orientation.dart.bk
  27. 0 0
      lib/service/game/plug_sport_wear.dart.bk
  28. 0 0
      lib/service/game/rule.dart.bk
  29. 0 0
      lib/service/game/rule_in_order.dart.bk
  30. 0 0
      lib/service/game/rule_in_order_allow_skip_cp.dart.bk
  31. 0 0
      lib/service/image.dart.bk
  32. 62 0
      lib/service/map/compass_updater.dart
  33. 289 0
      lib/service/map/game_model.dart
  34. 838 0
      lib/service/map/map.dart
  35. 266 0
      lib/service/map/map_status.dart
  36. 6 0
      lib/service/map/plug.dart
  37. 150 0
      lib/service/map/plug_orientation.dart
  38. 45 0
      lib/service/map/plug_orientation2.dart
  39. 0 0
      lib/view/app_need_update_view.dart.bk
  40. 5 5
      lib/view/home/dialog_special_warn.dart.bk
  41. 0 0
      lib/view/home/guardian_view.dart.bk
  42. 0 0
      lib/view/home/home_gallery_view.dart.bk
  43. 0 0
      lib/view/home/home_map_view.dart.bk
  44. 0 0
      lib/view/home/home_save_user_info_view.dart.bk
  45. 0 0
      lib/view/home/under_guardian_view.dart.bk
  46. 0 365
      lib/view/ingame/bottom_bar.dart
  47. 0 372
      lib/view/ingame/button_bar.dart
  48. 0 169
      lib/view/ingame/button_punch.dart
  49. 0 81
      lib/view/ingame/checked_cp_record.dart
  50. 0 0
      lib/view/ingame/common.dart
  51. 0 155
      lib/view/ingame/dialog/dialog_base.dart
  52. 0 23
      lib/view/ingame/dialog/dialog_button.dart
  53. 0 375
      lib/view/ingame/dialog/dialog_check_rich.dart
  54. 0 353
      lib/view/ingame/dialog/dialog_check_rich2.dart
  55. 0 199
      lib/view/ingame/dialog/dialog_check_text.dart
  56. 0 48
      lib/view/ingame/dialog/dialog_confirm_finish.dart
  57. 0 61
      lib/view/ingame/dialog/dialog_cp_order_err.dart
  58. 0 170
      lib/view/ingame/dialog/dialog_finish_result.dart
  59. 0 108
      lib/view/ingame/dialog/dialog_start_warn.dart
  60. 0 121
      lib/view/ingame/dialog_checked.dart
  61. 0 304
      lib/view/ingame/dialog_checked2.dart
  62. 0 352
      lib/view/ingame/game_compass/game_compass_base.dart
  63. 0 49
      lib/view/ingame/game_compass/game_compass_button.dart
  64. 0 27
      lib/view/ingame/game_compass/game_compass_top4_data.dart
  65. 0 138
      lib/view/ingame/game_guardian/guardian_controller.dart
  66. 0 162
      lib/view/ingame/game_guardian/guardian_watch_game_view.dart
  67. 0 302
      lib/view/ingame/game_guardian/layer_front_ui.dart
  68. 0 99
      lib/view/ingame/game_guardian/layer_under_guardian.dart
  69. 0 109
      lib/view/ingame/game_guardian/widget_point.dart
  70. 0 153
      lib/view/ingame/game_orienteering_assistant/game_orienteering_assistant_view.dart
  71. 0 140
      lib/view/ingame/game_std/button_punch.dart
  72. 0 150
      lib/view/ingame/game_std/dialog_finish.dart
  73. 0 598
      lib/view/ingame/game_std/game_std_controller.dart
  74. 0 51
      lib/view/ingame/game_std/game_std_view.dart
  75. 0 97
      lib/view/ingame/game_std/game_std_view_compass.dart
  76. 0 69
      lib/view/ingame/game_std/game_std_view_emap.dart
  77. 0 18
      lib/view/ingame/game_std/game_std_view_no_map.dart
  78. 0 19
      lib/view/ingame/game_std/game_std_view_paper_map.dart
  79. 0 59
      lib/view/ingame/game_std/info_view.dart
  80. 0 33
      lib/view/ingame/game_std/layer_compass.dart
  81. 0 49
      lib/view/ingame/game_std/layer_cp_start_bubble.dart
  82. 0 45
      lib/view/ingame/game_std/layer_cp_touch.dart
  83. 0 42
      lib/view/ingame/game_std/layer_front_ui.dart
  84. 0 363
      lib/view/ingame/game_std/layer_front_ui_bottom_bar.dart
  85. 0 364
      lib/view/ingame/game_std/layer_front_ui_button_bar.dart
  86. 0 31
      lib/view/ingame/game_std/layer_location.dart
  87. 0 34
      lib/view/ingame/game_std/layer_map_ruler.dart
  88. 0 96
      lib/view/ingame/game_std/layer_warn.dart
  89. 0 281
      lib/view/ingame/game_std/route_planning.dart
  90. 0 36
      lib/view/ingame/game_std/settlement_view.dart
  91. 0 249
      lib/view/ingame/game_std/utils.dart
  92. 0 517
      lib/view/ingame/in_game_controller.dart
  93. 0 181
      lib/view/ingame/in_game_loading.dart
  94. 0 62
      lib/view/ingame/in_game_loading2.dart
  95. 0 404
      lib/view/ingame/in_game_no_map_view.dart
  96. 0 75
      lib/view/ingame/in_game_view.dart
  97. 0 61
      lib/view/ingame/info_view.dart
  98. 0 56
      lib/view/ingame/instance_view.dart
  99. 0 29
      lib/view/ingame/layer/layer.dart
  100. 0 298
      lib/view/ingame/layer/layer_controller.dart

BIN
assets/images/common/page_bg_dark.png


BIN
assets/images/ic_flag_blue.png


BIN
assets/images/ic_flag_red.png


BIN
assets/images/ic_flag_yellow.png


BIN
assets/images/ic_radio_selected_gray.png


BIN
assets/images/ic_radio_selected_orange.png


+ 1132 - 0
lib/generated/to_app_api.pb.dart

@@ -0,0 +1,1132 @@
+//
+//  Generated code. Do not modify.
+//  source: to_app_api.proto
+//
+// @dart = 2.12
+
+// ignore_for_file: annotate_overrides, camel_case_types
+// ignore_for_file: constant_identifier_names, library_prefixes
+// ignore_for_file: non_constant_identifier_names, prefer_final_fields
+// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
+
+import 'dart:core' as $core;
+
+import 'package:fixnum/fixnum.dart' as $fixnum;
+import 'package:protobuf/protobuf.dart' as $pb;
+
+import 'base.pb.dart' as $1;
+import 'base.pbenum.dart' as $1;
+import 'google/protobuf/duration.pb.dart' as $3;
+import 'google/protobuf/timestamp.pb.dart' as $2;
+
+class ToGetBinaryByMd5Request extends $pb.GeneratedMessage {
+  factory ToGetBinaryByMd5Request() => create();
+  ToGetBinaryByMd5Request._() : super();
+  factory ToGetBinaryByMd5Request.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory ToGetBinaryByMd5Request.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ToGetBinaryByMd5Request', package: const $pb.PackageName(_omitMessageNames ? '' : 'toApp.v1'), createEmptyInstance: create)
+    ..a<$core.List<$core.int>>(1, _omitFieldNames ? '' : 'md5', $pb.PbFieldType.OY)
+    ..hasRequiredFields = false
+  ;
+
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  ToGetBinaryByMd5Request clone() => ToGetBinaryByMd5Request()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  ToGetBinaryByMd5Request copyWith(void Function(ToGetBinaryByMd5Request) updates) => super.copyWith((message) => updates(message as ToGetBinaryByMd5Request)) as ToGetBinaryByMd5Request;
+
+  $pb.BuilderInfo get info_ => _i;
+
+  @$core.pragma('dart2js:noInline')
+  static ToGetBinaryByMd5Request create() => ToGetBinaryByMd5Request._();
+  ToGetBinaryByMd5Request createEmptyInstance() => create();
+  static $pb.PbList<ToGetBinaryByMd5Request> createRepeated() => $pb.PbList<ToGetBinaryByMd5Request>();
+  @$core.pragma('dart2js:noInline')
+  static ToGetBinaryByMd5Request getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ToGetBinaryByMd5Request>(create);
+  static ToGetBinaryByMd5Request? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.List<$core.int> get md5 => $_getN(0);
+  @$pb.TagNumber(1)
+  set md5($core.List<$core.int> v) { $_setBytes(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasMd5() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearMd5() => clearField(1);
+}
+
+class GetServerTimeRp extends $pb.GeneratedMessage {
+  factory GetServerTimeRp() => create();
+  GetServerTimeRp._() : super();
+  factory GetServerTimeRp.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory GetServerTimeRp.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'GetServerTimeRp', package: const $pb.PackageName(_omitMessageNames ? '' : 'toApp.v1'), createEmptyInstance: create)
+    ..aInt64(1, _omitFieldNames ? '' : 'millisecondStamp', protoName: 'millisecondStamp')
+    ..hasRequiredFields = false
+  ;
+
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  GetServerTimeRp clone() => GetServerTimeRp()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  GetServerTimeRp copyWith(void Function(GetServerTimeRp) updates) => super.copyWith((message) => updates(message as GetServerTimeRp)) as GetServerTimeRp;
+
+  $pb.BuilderInfo get info_ => _i;
+
+  @$core.pragma('dart2js:noInline')
+  static GetServerTimeRp create() => GetServerTimeRp._();
+  GetServerTimeRp createEmptyInstance() => create();
+  static $pb.PbList<GetServerTimeRp> createRepeated() => $pb.PbList<GetServerTimeRp>();
+  @$core.pragma('dart2js:noInline')
+  static GetServerTimeRp getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<GetServerTimeRp>(create);
+  static GetServerTimeRp? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $fixnum.Int64 get millisecondStamp => $_getI64(0);
+  @$pb.TagNumber(1)
+  set millisecondStamp($fixnum.Int64 v) { $_setInt64(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasMillisecondStamp() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearMillisecondStamp() => clearField(1);
+}
+
+class ToSendCodeToPhoneRequestV2 extends $pb.GeneratedMessage {
+  factory ToSendCodeToPhoneRequestV2() => create();
+  ToSendCodeToPhoneRequestV2._() : super();
+  factory ToSendCodeToPhoneRequestV2.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory ToSendCodeToPhoneRequestV2.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ToSendCodeToPhoneRequestV2', package: const $pb.PackageName(_omitMessageNames ? '' : 'toApp.v1'), createEmptyInstance: create)
+    ..aOS(1, _omitFieldNames ? '' : 'phone')
+    ..e<$1.SmsType>(2, _omitFieldNames ? '' : 'smsType', $pb.PbFieldType.OE, protoName: 'smsType', defaultOrMaker: $1.SmsType.UnKnow, valueOf: $1.SmsType.valueOf, enumValues: $1.SmsType.values)
+    ..hasRequiredFields = false
+  ;
+
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  ToSendCodeToPhoneRequestV2 clone() => ToSendCodeToPhoneRequestV2()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  ToSendCodeToPhoneRequestV2 copyWith(void Function(ToSendCodeToPhoneRequestV2) updates) => super.copyWith((message) => updates(message as ToSendCodeToPhoneRequestV2)) as ToSendCodeToPhoneRequestV2;
+
+  $pb.BuilderInfo get info_ => _i;
+
+  @$core.pragma('dart2js:noInline')
+  static ToSendCodeToPhoneRequestV2 create() => ToSendCodeToPhoneRequestV2._();
+  ToSendCodeToPhoneRequestV2 createEmptyInstance() => create();
+  static $pb.PbList<ToSendCodeToPhoneRequestV2> createRepeated() => $pb.PbList<ToSendCodeToPhoneRequestV2>();
+  @$core.pragma('dart2js:noInline')
+  static ToSendCodeToPhoneRequestV2 getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ToSendCodeToPhoneRequestV2>(create);
+  static ToSendCodeToPhoneRequestV2? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.String get phone => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set phone($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasPhone() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearPhone() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $1.SmsType get smsType => $_getN(1);
+  @$pb.TagNumber(2)
+  set smsType($1.SmsType v) { setField(2, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasSmsType() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearSmsType() => clearField(2);
+}
+
+class ToSignInRequestV2 extends $pb.GeneratedMessage {
+  factory ToSignInRequestV2() => create();
+  ToSignInRequestV2._() : super();
+  factory ToSignInRequestV2.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory ToSignInRequestV2.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ToSignInRequestV2', package: const $pb.PackageName(_omitMessageNames ? '' : 'toApp.v1'), createEmptyInstance: create)
+    ..aOS(1, _omitFieldNames ? '' : 'userCode', protoName: 'userCode')
+    ..aOS(2, _omitFieldNames ? '' : 'password')
+    ..aOS(3, _omitFieldNames ? '' : 'ip')
+    ..hasRequiredFields = false
+  ;
+
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  ToSignInRequestV2 clone() => ToSignInRequestV2()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  ToSignInRequestV2 copyWith(void Function(ToSignInRequestV2) updates) => super.copyWith((message) => updates(message as ToSignInRequestV2)) as ToSignInRequestV2;
+
+  $pb.BuilderInfo get info_ => _i;
+
+  @$core.pragma('dart2js:noInline')
+  static ToSignInRequestV2 create() => ToSignInRequestV2._();
+  ToSignInRequestV2 createEmptyInstance() => create();
+  static $pb.PbList<ToSignInRequestV2> createRepeated() => $pb.PbList<ToSignInRequestV2>();
+  @$core.pragma('dart2js:noInline')
+  static ToSignInRequestV2 getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ToSignInRequestV2>(create);
+  static ToSignInRequestV2? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.String get userCode => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set userCode($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasUserCode() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearUserCode() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.String get password => $_getSZ(1);
+  @$pb.TagNumber(2)
+  set password($core.String v) { $_setString(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasPassword() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearPassword() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $core.String get ip => $_getSZ(2);
+  @$pb.TagNumber(3)
+  set ip($core.String v) { $_setString(2, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasIp() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearIp() => clearField(3);
+}
+
+class MapListRequestV2 extends $pb.GeneratedMessage {
+  factory MapListRequestV2() => create();
+  MapListRequestV2._() : super();
+  factory MapListRequestV2.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory MapListRequestV2.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'MapListRequestV2', package: const $pb.PackageName(_omitMessageNames ? '' : 'toApp.v1'), createEmptyInstance: create)
+    ..aOM<$1.Position>(1, _omitFieldNames ? '' : 'position', subBuilder: $1.Position.create)
+    ..a<$core.int>(2, _omitFieldNames ? '' : 'offset', $pb.PbFieldType.O3)
+    ..a<$core.int>(3, _omitFieldNames ? '' : 'limit', $pb.PbFieldType.O3)
+    ..hasRequiredFields = false
+  ;
+
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  MapListRequestV2 clone() => MapListRequestV2()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  MapListRequestV2 copyWith(void Function(MapListRequestV2) updates) => super.copyWith((message) => updates(message as MapListRequestV2)) as MapListRequestV2;
+
+  $pb.BuilderInfo get info_ => _i;
+
+  @$core.pragma('dart2js:noInline')
+  static MapListRequestV2 create() => MapListRequestV2._();
+  MapListRequestV2 createEmptyInstance() => create();
+  static $pb.PbList<MapListRequestV2> createRepeated() => $pb.PbList<MapListRequestV2>();
+  @$core.pragma('dart2js:noInline')
+  static MapListRequestV2 getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<MapListRequestV2>(create);
+  static MapListRequestV2? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $1.Position get position => $_getN(0);
+  @$pb.TagNumber(1)
+  set position($1.Position v) { setField(1, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasPosition() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearPosition() => clearField(1);
+  @$pb.TagNumber(1)
+  $1.Position ensurePosition() => $_ensure(0);
+
+  @$pb.TagNumber(2)
+  $core.int get offset => $_getIZ(1);
+  @$pb.TagNumber(2)
+  set offset($core.int v) { $_setSignedInt32(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasOffset() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearOffset() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $core.int get limit => $_getIZ(2);
+  @$pb.TagNumber(3)
+  set limit($core.int v) { $_setSignedInt32(2, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasLimit() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearLimit() => clearField(3);
+}
+
+class ToMapListReplyV2 extends $pb.GeneratedMessage {
+  factory ToMapListReplyV2() => create();
+  ToMapListReplyV2._() : super();
+  factory ToMapListReplyV2.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory ToMapListReplyV2.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ToMapListReplyV2', package: const $pb.PackageName(_omitMessageNames ? '' : 'toApp.v1'), createEmptyInstance: create)
+    ..pc<ToMapSimpleV2>(1, _omitFieldNames ? '' : 'list', $pb.PbFieldType.PM, subBuilder: ToMapSimpleV2.create)
+    ..hasRequiredFields = false
+  ;
+
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  ToMapListReplyV2 clone() => ToMapListReplyV2()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  ToMapListReplyV2 copyWith(void Function(ToMapListReplyV2) updates) => super.copyWith((message) => updates(message as ToMapListReplyV2)) as ToMapListReplyV2;
+
+  $pb.BuilderInfo get info_ => _i;
+
+  @$core.pragma('dart2js:noInline')
+  static ToMapListReplyV2 create() => ToMapListReplyV2._();
+  ToMapListReplyV2 createEmptyInstance() => create();
+  static $pb.PbList<ToMapListReplyV2> createRepeated() => $pb.PbList<ToMapListReplyV2>();
+  @$core.pragma('dart2js:noInline')
+  static ToMapListReplyV2 getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ToMapListReplyV2>(create);
+  static ToMapListReplyV2? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.List<ToMapSimpleV2> get list => $_getList(0);
+}
+
+class ToMapSimpleV2 extends $pb.GeneratedMessage {
+  factory ToMapSimpleV2() => create();
+  ToMapSimpleV2._() : super();
+  factory ToMapSimpleV2.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory ToMapSimpleV2.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ToMapSimpleV2', package: const $pb.PackageName(_omitMessageNames ? '' : 'toApp.v1'), createEmptyInstance: create)
+    ..a<$core.int>(1, _omitFieldNames ? '' : 'mapId', $pb.PbFieldType.O3, protoName: 'mapId')
+    ..aOS(2, _omitFieldNames ? '' : 'name')
+    ..a<$core.int>(3, _omitFieldNames ? '' : 'mapScaleNumber', $pb.PbFieldType.O3, protoName: 'mapScaleNumber')
+    ..aOS(4, _omitFieldNames ? '' : 'description')
+    ..a<$core.double>(5, _omitFieldNames ? '' : 'distance', $pb.PbFieldType.OD)
+    ..aOM<$1.NetImage>(6, _omitFieldNames ? '' : 'image', subBuilder: $1.NetImage.create)
+    ..hasRequiredFields = false
+  ;
+
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  ToMapSimpleV2 clone() => ToMapSimpleV2()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  ToMapSimpleV2 copyWith(void Function(ToMapSimpleV2) updates) => super.copyWith((message) => updates(message as ToMapSimpleV2)) as ToMapSimpleV2;
+
+  $pb.BuilderInfo get info_ => _i;
+
+  @$core.pragma('dart2js:noInline')
+  static ToMapSimpleV2 create() => ToMapSimpleV2._();
+  ToMapSimpleV2 createEmptyInstance() => create();
+  static $pb.PbList<ToMapSimpleV2> createRepeated() => $pb.PbList<ToMapSimpleV2>();
+  @$core.pragma('dart2js:noInline')
+  static ToMapSimpleV2 getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ToMapSimpleV2>(create);
+  static ToMapSimpleV2? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.int get mapId => $_getIZ(0);
+  @$pb.TagNumber(1)
+  set mapId($core.int v) { $_setSignedInt32(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasMapId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearMapId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.String get name => $_getSZ(1);
+  @$pb.TagNumber(2)
+  set name($core.String v) { $_setString(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasName() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearName() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $core.int get mapScaleNumber => $_getIZ(2);
+  @$pb.TagNumber(3)
+  set mapScaleNumber($core.int v) { $_setSignedInt32(2, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasMapScaleNumber() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearMapScaleNumber() => clearField(3);
+
+  @$pb.TagNumber(4)
+  $core.String get description => $_getSZ(3);
+  @$pb.TagNumber(4)
+  set description($core.String v) { $_setString(3, v); }
+  @$pb.TagNumber(4)
+  $core.bool hasDescription() => $_has(3);
+  @$pb.TagNumber(4)
+  void clearDescription() => clearField(4);
+
+  @$pb.TagNumber(5)
+  $core.double get distance => $_getN(4);
+  @$pb.TagNumber(5)
+  set distance($core.double v) { $_setDouble(4, v); }
+  @$pb.TagNumber(5)
+  $core.bool hasDistance() => $_has(4);
+  @$pb.TagNumber(5)
+  void clearDistance() => clearField(5);
+
+  @$pb.TagNumber(6)
+  $1.NetImage get image => $_getN(5);
+  @$pb.TagNumber(6)
+  set image($1.NetImage v) { setField(6, v); }
+  @$pb.TagNumber(6)
+  $core.bool hasImage() => $_has(5);
+  @$pb.TagNumber(6)
+  void clearImage() => clearField(6);
+  @$pb.TagNumber(6)
+  $1.NetImage ensureImage() => $_ensure(5);
+}
+
+class ToMapInfoV2 extends $pb.GeneratedMessage {
+  factory ToMapInfoV2() => create();
+  ToMapInfoV2._() : super();
+  factory ToMapInfoV2.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory ToMapInfoV2.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ToMapInfoV2', package: const $pb.PackageName(_omitMessageNames ? '' : 'toApp.v1'), createEmptyInstance: create)
+    ..a<$core.int>(1, _omitFieldNames ? '' : 'mapId', $pb.PbFieldType.O3, protoName: 'mapId')
+    ..aOS(2, _omitFieldNames ? '' : 'mapName', protoName: 'mapName')
+    ..aOM<$1.NetImage>(3, _omitFieldNames ? '' : 'zipImage', protoName: 'zipImage', subBuilder: $1.NetImage.create)
+    ..hasRequiredFields = false
+  ;
+
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  ToMapInfoV2 clone() => ToMapInfoV2()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  ToMapInfoV2 copyWith(void Function(ToMapInfoV2) updates) => super.copyWith((message) => updates(message as ToMapInfoV2)) as ToMapInfoV2;
+
+  $pb.BuilderInfo get info_ => _i;
+
+  @$core.pragma('dart2js:noInline')
+  static ToMapInfoV2 create() => ToMapInfoV2._();
+  ToMapInfoV2 createEmptyInstance() => create();
+  static $pb.PbList<ToMapInfoV2> createRepeated() => $pb.PbList<ToMapInfoV2>();
+  @$core.pragma('dart2js:noInline')
+  static ToMapInfoV2 getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ToMapInfoV2>(create);
+  static ToMapInfoV2? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.int get mapId => $_getIZ(0);
+  @$pb.TagNumber(1)
+  set mapId($core.int v) { $_setSignedInt32(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasMapId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearMapId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.String get mapName => $_getSZ(1);
+  @$pb.TagNumber(2)
+  set mapName($core.String v) { $_setString(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasMapName() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearMapName() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $1.NetImage get zipImage => $_getN(2);
+  @$pb.TagNumber(3)
+  set zipImage($1.NetImage v) { setField(3, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasZipImage() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearZipImage() => clearField(3);
+  @$pb.TagNumber(3)
+  $1.NetImage ensureZipImage() => $_ensure(2);
+}
+
+class ToUserDetailQueryRequestV2 extends $pb.GeneratedMessage {
+  factory ToUserDetailQueryRequestV2() => create();
+  ToUserDetailQueryRequestV2._() : super();
+  factory ToUserDetailQueryRequestV2.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory ToUserDetailQueryRequestV2.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ToUserDetailQueryRequestV2', package: const $pb.PackageName(_omitMessageNames ? '' : 'toApp.v1'), createEmptyInstance: create)
+    ..a<$core.int>(1, _omitFieldNames ? '' : 'mapId', $pb.PbFieldType.O3, protoName: 'mapId')
+    ..aOB(2, _omitFieldNames ? '' : 'isFullQuery', protoName: 'isFullQuery')
+    ..hasRequiredFields = false
+  ;
+
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  ToUserDetailQueryRequestV2 clone() => ToUserDetailQueryRequestV2()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  ToUserDetailQueryRequestV2 copyWith(void Function(ToUserDetailQueryRequestV2) updates) => super.copyWith((message) => updates(message as ToUserDetailQueryRequestV2)) as ToUserDetailQueryRequestV2;
+
+  $pb.BuilderInfo get info_ => _i;
+
+  @$core.pragma('dart2js:noInline')
+  static ToUserDetailQueryRequestV2 create() => ToUserDetailQueryRequestV2._();
+  ToUserDetailQueryRequestV2 createEmptyInstance() => create();
+  static $pb.PbList<ToUserDetailQueryRequestV2> createRepeated() => $pb.PbList<ToUserDetailQueryRequestV2>();
+  @$core.pragma('dart2js:noInline')
+  static ToUserDetailQueryRequestV2 getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ToUserDetailQueryRequestV2>(create);
+  static ToUserDetailQueryRequestV2? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.int get mapId => $_getIZ(0);
+  @$pb.TagNumber(1)
+  set mapId($core.int v) { $_setSignedInt32(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasMapId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearMapId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.bool get isFullQuery => $_getBF(1);
+  @$pb.TagNumber(2)
+  set isFullQuery($core.bool v) { $_setBool(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasIsFullQuery() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearIsFullQuery() => clearField(2);
+}
+
+class ToUserDetailQueryReplyV2 extends $pb.GeneratedMessage {
+  factory ToUserDetailQueryReplyV2() => create();
+  ToUserDetailQueryReplyV2._() : super();
+  factory ToUserDetailQueryReplyV2.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory ToUserDetailQueryReplyV2.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ToUserDetailQueryReplyV2', package: const $pb.PackageName(_omitMessageNames ? '' : 'toApp.v1'), createEmptyInstance: create)
+    ..pc<ToActionInfo>(1, _omitFieldNames ? '' : 'list', $pb.PbFieldType.PM, subBuilder: ToActionInfo.create)
+    ..hasRequiredFields = false
+  ;
+
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  ToUserDetailQueryReplyV2 clone() => ToUserDetailQueryReplyV2()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  ToUserDetailQueryReplyV2 copyWith(void Function(ToUserDetailQueryReplyV2) updates) => super.copyWith((message) => updates(message as ToUserDetailQueryReplyV2)) as ToUserDetailQueryReplyV2;
+
+  $pb.BuilderInfo get info_ => _i;
+
+  @$core.pragma('dart2js:noInline')
+  static ToUserDetailQueryReplyV2 create() => ToUserDetailQueryReplyV2._();
+  ToUserDetailQueryReplyV2 createEmptyInstance() => create();
+  static $pb.PbList<ToUserDetailQueryReplyV2> createRepeated() => $pb.PbList<ToUserDetailQueryReplyV2>();
+  @$core.pragma('dart2js:noInline')
+  static ToUserDetailQueryReplyV2 getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ToUserDetailQueryReplyV2>(create);
+  static ToUserDetailQueryReplyV2? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.List<ToActionInfo> get list => $_getList(0);
+}
+
+class ToActionInfo extends $pb.GeneratedMessage {
+  factory ToActionInfo() => create();
+  ToActionInfo._() : super();
+  factory ToActionInfo.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory ToActionInfo.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ToActionInfo', package: const $pb.PackageName(_omitMessageNames ? '' : 'toApp.v1'), createEmptyInstance: create)
+    ..a<$core.int>(1, _omitFieldNames ? '' : 'actId', $pb.PbFieldType.O3, protoName: 'actId')
+    ..aOS(2, _omitFieldNames ? '' : 'actName', protoName: 'actName')
+    ..a<$core.int>(3, _omitFieldNames ? '' : 'totalControlNum', $pb.PbFieldType.O3, protoName: 'totalControlNum')
+    ..pc<ToOrienteerInGameInfo>(4, _omitFieldNames ? '' : 'userList', $pb.PbFieldType.PM, protoName: 'userList', subBuilder: ToOrienteerInGameInfo.create)
+    ..hasRequiredFields = false
+  ;
+
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  ToActionInfo clone() => ToActionInfo()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  ToActionInfo copyWith(void Function(ToActionInfo) updates) => super.copyWith((message) => updates(message as ToActionInfo)) as ToActionInfo;
+
+  $pb.BuilderInfo get info_ => _i;
+
+  @$core.pragma('dart2js:noInline')
+  static ToActionInfo create() => ToActionInfo._();
+  ToActionInfo createEmptyInstance() => create();
+  static $pb.PbList<ToActionInfo> createRepeated() => $pb.PbList<ToActionInfo>();
+  @$core.pragma('dart2js:noInline')
+  static ToActionInfo getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ToActionInfo>(create);
+  static ToActionInfo? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.int get actId => $_getIZ(0);
+  @$pb.TagNumber(1)
+  set actId($core.int v) { $_setSignedInt32(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasActId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearActId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.String get actName => $_getSZ(1);
+  @$pb.TagNumber(2)
+  set actName($core.String v) { $_setString(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasActName() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearActName() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $core.int get totalControlNum => $_getIZ(2);
+  @$pb.TagNumber(3)
+  set totalControlNum($core.int v) { $_setSignedInt32(2, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasTotalControlNum() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearTotalControlNum() => clearField(3);
+
+  @$pb.TagNumber(4)
+  $core.List<ToOrienteerInGameInfo> get userList => $_getList(3);
+}
+
+class ToOrienteerInGameInfo extends $pb.GeneratedMessage {
+  factory ToOrienteerInGameInfo() => create();
+  ToOrienteerInGameInfo._() : super();
+  factory ToOrienteerInGameInfo.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory ToOrienteerInGameInfo.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ToOrienteerInGameInfo', package: const $pb.PackageName(_omitMessageNames ? '' : 'toApp.v1'), createEmptyInstance: create)
+    ..a<$core.int>(1, _omitFieldNames ? '' : 'UserId', $pb.PbFieldType.O3, protoName: 'UserId')
+    ..aOM<OrienteerBaseInfo>(2, _omitFieldNames ? '' : 'baseInfo', protoName: 'baseInfo', subBuilder: OrienteerBaseInfo.create)
+    ..aOM<OrienteerGpsInfo>(3, _omitFieldNames ? '' : 'gpsInfo', protoName: 'gpsInfo', subBuilder: OrienteerGpsInfo.create)
+    ..aOM<OrienteerHrInfo>(4, _omitFieldNames ? '' : 'hrInfo', protoName: 'hrInfo', subBuilder: OrienteerHrInfo.create)
+    ..aOM<OrienteerGameSaveInfo>(5, _omitFieldNames ? '' : 'gameSaveInfo', protoName: 'gameSaveInfo', subBuilder: OrienteerGameSaveInfo.create)
+    ..aOM<CourseBaseInfo>(6, _omitFieldNames ? '' : 'courseBaseInfo', protoName: 'courseBaseInfo', subBuilder: CourseBaseInfo.create)
+    ..aOM<OrienteerOtherInfo>(7, _omitFieldNames ? '' : 'otherInfo', protoName: 'otherInfo', subBuilder: OrienteerOtherInfo.create)
+    ..hasRequiredFields = false
+  ;
+
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  ToOrienteerInGameInfo clone() => ToOrienteerInGameInfo()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  ToOrienteerInGameInfo copyWith(void Function(ToOrienteerInGameInfo) updates) => super.copyWith((message) => updates(message as ToOrienteerInGameInfo)) as ToOrienteerInGameInfo;
+
+  $pb.BuilderInfo get info_ => _i;
+
+  @$core.pragma('dart2js:noInline')
+  static ToOrienteerInGameInfo create() => ToOrienteerInGameInfo._();
+  ToOrienteerInGameInfo createEmptyInstance() => create();
+  static $pb.PbList<ToOrienteerInGameInfo> createRepeated() => $pb.PbList<ToOrienteerInGameInfo>();
+  @$core.pragma('dart2js:noInline')
+  static ToOrienteerInGameInfo getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ToOrienteerInGameInfo>(create);
+  static ToOrienteerInGameInfo? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.int get userId => $_getIZ(0);
+  @$pb.TagNumber(1)
+  set userId($core.int v) { $_setSignedInt32(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasUserId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearUserId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  OrienteerBaseInfo get baseInfo => $_getN(1);
+  @$pb.TagNumber(2)
+  set baseInfo(OrienteerBaseInfo v) { setField(2, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasBaseInfo() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearBaseInfo() => clearField(2);
+  @$pb.TagNumber(2)
+  OrienteerBaseInfo ensureBaseInfo() => $_ensure(1);
+
+  @$pb.TagNumber(3)
+  OrienteerGpsInfo get gpsInfo => $_getN(2);
+  @$pb.TagNumber(3)
+  set gpsInfo(OrienteerGpsInfo v) { setField(3, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasGpsInfo() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearGpsInfo() => clearField(3);
+  @$pb.TagNumber(3)
+  OrienteerGpsInfo ensureGpsInfo() => $_ensure(2);
+
+  @$pb.TagNumber(4)
+  OrienteerHrInfo get hrInfo => $_getN(3);
+  @$pb.TagNumber(4)
+  set hrInfo(OrienteerHrInfo v) { setField(4, v); }
+  @$pb.TagNumber(4)
+  $core.bool hasHrInfo() => $_has(3);
+  @$pb.TagNumber(4)
+  void clearHrInfo() => clearField(4);
+  @$pb.TagNumber(4)
+  OrienteerHrInfo ensureHrInfo() => $_ensure(3);
+
+  @$pb.TagNumber(5)
+  OrienteerGameSaveInfo get gameSaveInfo => $_getN(4);
+  @$pb.TagNumber(5)
+  set gameSaveInfo(OrienteerGameSaveInfo v) { setField(5, v); }
+  @$pb.TagNumber(5)
+  $core.bool hasGameSaveInfo() => $_has(4);
+  @$pb.TagNumber(5)
+  void clearGameSaveInfo() => clearField(5);
+  @$pb.TagNumber(5)
+  OrienteerGameSaveInfo ensureGameSaveInfo() => $_ensure(4);
+
+  @$pb.TagNumber(6)
+  CourseBaseInfo get courseBaseInfo => $_getN(5);
+  @$pb.TagNumber(6)
+  set courseBaseInfo(CourseBaseInfo v) { setField(6, v); }
+  @$pb.TagNumber(6)
+  $core.bool hasCourseBaseInfo() => $_has(5);
+  @$pb.TagNumber(6)
+  void clearCourseBaseInfo() => clearField(6);
+  @$pb.TagNumber(6)
+  CourseBaseInfo ensureCourseBaseInfo() => $_ensure(5);
+
+  @$pb.TagNumber(7)
+  OrienteerOtherInfo get otherInfo => $_getN(6);
+  @$pb.TagNumber(7)
+  set otherInfo(OrienteerOtherInfo v) { setField(7, v); }
+  @$pb.TagNumber(7)
+  $core.bool hasOtherInfo() => $_has(6);
+  @$pb.TagNumber(7)
+  void clearOtherInfo() => clearField(7);
+  @$pb.TagNumber(7)
+  OrienteerOtherInfo ensureOtherInfo() => $_ensure(6);
+}
+
+class OrienteerBaseInfo extends $pb.GeneratedMessage {
+  factory OrienteerBaseInfo() => create();
+  OrienteerBaseInfo._() : super();
+  factory OrienteerBaseInfo.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory OrienteerBaseInfo.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'OrienteerBaseInfo', package: const $pb.PackageName(_omitMessageNames ? '' : 'toApp.v1'), createEmptyInstance: create)
+    ..aOS(1, _omitFieldNames ? '' : 'Name', protoName: 'Name')
+    ..aOS(2, _omitFieldNames ? '' : 'Phone', protoName: 'Phone')
+    ..aOS(3, _omitFieldNames ? '' : 'HeadUrl', protoName: 'HeadUrl')
+    ..hasRequiredFields = false
+  ;
+
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  OrienteerBaseInfo clone() => OrienteerBaseInfo()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  OrienteerBaseInfo copyWith(void Function(OrienteerBaseInfo) updates) => super.copyWith((message) => updates(message as OrienteerBaseInfo)) as OrienteerBaseInfo;
+
+  $pb.BuilderInfo get info_ => _i;
+
+  @$core.pragma('dart2js:noInline')
+  static OrienteerBaseInfo create() => OrienteerBaseInfo._();
+  OrienteerBaseInfo createEmptyInstance() => create();
+  static $pb.PbList<OrienteerBaseInfo> createRepeated() => $pb.PbList<OrienteerBaseInfo>();
+  @$core.pragma('dart2js:noInline')
+  static OrienteerBaseInfo getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<OrienteerBaseInfo>(create);
+  static OrienteerBaseInfo? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.String get name => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set name($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasName() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearName() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.String get phone => $_getSZ(1);
+  @$pb.TagNumber(2)
+  set phone($core.String v) { $_setString(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasPhone() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearPhone() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $core.String get headUrl => $_getSZ(2);
+  @$pb.TagNumber(3)
+  set headUrl($core.String v) { $_setString(2, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasHeadUrl() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearHeadUrl() => clearField(3);
+}
+
+class OrienteerGpsInfo extends $pb.GeneratedMessage {
+  factory OrienteerGpsInfo() => create();
+  OrienteerGpsInfo._() : super();
+  factory OrienteerGpsInfo.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory OrienteerGpsInfo.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'OrienteerGpsInfo', package: const $pb.PackageName(_omitMessageNames ? '' : 'toApp.v1'), createEmptyInstance: create)
+    ..pc<$1.GameGpsInfo>(1, _omitFieldNames ? '' : 'gameGpsInfos', $pb.PbFieldType.PM, protoName: 'gameGpsInfos', subBuilder: $1.GameGpsInfo.create)
+    ..a<$core.int>(2, _omitFieldNames ? '' : 'Distance', $pb.PbFieldType.O3, protoName: 'Distance')
+    ..a<$core.int>(3, _omitFieldNames ? '' : 'Pace', $pb.PbFieldType.O3, protoName: 'Pace')
+    ..hasRequiredFields = false
+  ;
+
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  OrienteerGpsInfo clone() => OrienteerGpsInfo()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  OrienteerGpsInfo copyWith(void Function(OrienteerGpsInfo) updates) => super.copyWith((message) => updates(message as OrienteerGpsInfo)) as OrienteerGpsInfo;
+
+  $pb.BuilderInfo get info_ => _i;
+
+  @$core.pragma('dart2js:noInline')
+  static OrienteerGpsInfo create() => OrienteerGpsInfo._();
+  OrienteerGpsInfo createEmptyInstance() => create();
+  static $pb.PbList<OrienteerGpsInfo> createRepeated() => $pb.PbList<OrienteerGpsInfo>();
+  @$core.pragma('dart2js:noInline')
+  static OrienteerGpsInfo getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<OrienteerGpsInfo>(create);
+  static OrienteerGpsInfo? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.List<$1.GameGpsInfo> get gameGpsInfos => $_getList(0);
+
+  @$pb.TagNumber(2)
+  $core.int get distance => $_getIZ(1);
+  @$pb.TagNumber(2)
+  set distance($core.int v) { $_setSignedInt32(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasDistance() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearDistance() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $core.int get pace => $_getIZ(2);
+  @$pb.TagNumber(3)
+  set pace($core.int v) { $_setSignedInt32(2, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasPace() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearPace() => clearField(3);
+}
+
+class OrienteerHrInfo extends $pb.GeneratedMessage {
+  factory OrienteerHrInfo() => create();
+  OrienteerHrInfo._() : super();
+  factory OrienteerHrInfo.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory OrienteerHrInfo.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'OrienteerHrInfo', package: const $pb.PackageName(_omitMessageNames ? '' : 'toApp.v1'), createEmptyInstance: create)
+    ..pc<$1.HeartRate>(1, _omitFieldNames ? '' : 'hrInfo', $pb.PbFieldType.PM, protoName: 'hrInfo', subBuilder: $1.HeartRate.create)
+    ..hasRequiredFields = false
+  ;
+
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  OrienteerHrInfo clone() => OrienteerHrInfo()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  OrienteerHrInfo copyWith(void Function(OrienteerHrInfo) updates) => super.copyWith((message) => updates(message as OrienteerHrInfo)) as OrienteerHrInfo;
+
+  $pb.BuilderInfo get info_ => _i;
+
+  @$core.pragma('dart2js:noInline')
+  static OrienteerHrInfo create() => OrienteerHrInfo._();
+  OrienteerHrInfo createEmptyInstance() => create();
+  static $pb.PbList<OrienteerHrInfo> createRepeated() => $pb.PbList<OrienteerHrInfo>();
+  @$core.pragma('dart2js:noInline')
+  static OrienteerHrInfo getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<OrienteerHrInfo>(create);
+  static OrienteerHrInfo? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.List<$1.HeartRate> get hrInfo => $_getList(0);
+}
+
+class OrienteerOtherInfo extends $pb.GeneratedMessage {
+  factory OrienteerOtherInfo() => create();
+  OrienteerOtherInfo._() : super();
+  factory OrienteerOtherInfo.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory OrienteerOtherInfo.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'OrienteerOtherInfo', package: const $pb.PackageName(_omitMessageNames ? '' : 'toApp.v1'), createEmptyInstance: create)
+    ..a<$core.int>(1, _omitFieldNames ? '' : 'StepNum', $pb.PbFieldType.O3, protoName: 'StepNum')
+    ..hasRequiredFields = false
+  ;
+
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  OrienteerOtherInfo clone() => OrienteerOtherInfo()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  OrienteerOtherInfo copyWith(void Function(OrienteerOtherInfo) updates) => super.copyWith((message) => updates(message as OrienteerOtherInfo)) as OrienteerOtherInfo;
+
+  $pb.BuilderInfo get info_ => _i;
+
+  @$core.pragma('dart2js:noInline')
+  static OrienteerOtherInfo create() => OrienteerOtherInfo._();
+  OrienteerOtherInfo createEmptyInstance() => create();
+  static $pb.PbList<OrienteerOtherInfo> createRepeated() => $pb.PbList<OrienteerOtherInfo>();
+  @$core.pragma('dart2js:noInline')
+  static OrienteerOtherInfo getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<OrienteerOtherInfo>(create);
+  static OrienteerOtherInfo? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.int get stepNum => $_getIZ(0);
+  @$pb.TagNumber(1)
+  set stepNum($core.int v) { $_setSignedInt32(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasStepNum() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearStepNum() => clearField(1);
+}
+
+class CourseBaseInfo extends $pb.GeneratedMessage {
+  factory CourseBaseInfo() => create();
+  CourseBaseInfo._() : super();
+  factory CourseBaseInfo.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory CourseBaseInfo.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'CourseBaseInfo', package: const $pb.PackageName(_omitMessageNames ? '' : 'toApp.v1'), createEmptyInstance: create)
+    ..a<$core.int>(1, _omitFieldNames ? '' : 'CourseId', $pb.PbFieldType.O3, protoName: 'CourseId')
+    ..aOS(2, _omitFieldNames ? '' : 'CourseName', protoName: 'CourseName')
+    ..pc<ToControlPoint>(3, _omitFieldNames ? '' : 'controlPointSortedList', $pb.PbFieldType.PM, protoName: 'controlPointSortedList', subBuilder: ToControlPoint.create)
+    ..hasRequiredFields = false
+  ;
+
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  CourseBaseInfo clone() => CourseBaseInfo()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  CourseBaseInfo copyWith(void Function(CourseBaseInfo) updates) => super.copyWith((message) => updates(message as CourseBaseInfo)) as CourseBaseInfo;
+
+  $pb.BuilderInfo get info_ => _i;
+
+  @$core.pragma('dart2js:noInline')
+  static CourseBaseInfo create() => CourseBaseInfo._();
+  CourseBaseInfo createEmptyInstance() => create();
+  static $pb.PbList<CourseBaseInfo> createRepeated() => $pb.PbList<CourseBaseInfo>();
+  @$core.pragma('dart2js:noInline')
+  static CourseBaseInfo getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CourseBaseInfo>(create);
+  static CourseBaseInfo? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.int get courseId => $_getIZ(0);
+  @$pb.TagNumber(1)
+  set courseId($core.int v) { $_setSignedInt32(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasCourseId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearCourseId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.String get courseName => $_getSZ(1);
+  @$pb.TagNumber(2)
+  set courseName($core.String v) { $_setString(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasCourseName() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearCourseName() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $core.List<ToControlPoint> get controlPointSortedList => $_getList(2);
+}
+
+class ToControlPoint extends $pb.GeneratedMessage {
+  factory ToControlPoint() => create();
+  ToControlPoint._() : super();
+  factory ToControlPoint.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory ToControlPoint.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ToControlPoint', package: const $pb.PackageName(_omitMessageNames ? '' : 'toApp.v1'), createEmptyInstance: create)
+    ..aInt64(1, _omitFieldNames ? '' : 'id')
+    ..aOS(2, _omitFieldNames ? '' : 'sn')
+    ..aOM<$1.Position>(5, _omitFieldNames ? '' : 'ciPosition', protoName: 'ciPosition', subBuilder: $1.Position.create)
+    ..hasRequiredFields = false
+  ;
+
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  ToControlPoint clone() => ToControlPoint()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  ToControlPoint copyWith(void Function(ToControlPoint) updates) => super.copyWith((message) => updates(message as ToControlPoint)) as ToControlPoint;
+
+  $pb.BuilderInfo get info_ => _i;
+
+  @$core.pragma('dart2js:noInline')
+  static ToControlPoint create() => ToControlPoint._();
+  ToControlPoint createEmptyInstance() => create();
+  static $pb.PbList<ToControlPoint> createRepeated() => $pb.PbList<ToControlPoint>();
+  @$core.pragma('dart2js:noInline')
+  static ToControlPoint getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ToControlPoint>(create);
+  static ToControlPoint? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $fixnum.Int64 get id => $_getI64(0);
+  @$pb.TagNumber(1)
+  set id($fixnum.Int64 v) { $_setInt64(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.String get sn => $_getSZ(1);
+  @$pb.TagNumber(2)
+  set sn($core.String v) { $_setString(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasSn() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearSn() => clearField(2);
+
+  @$pb.TagNumber(5)
+  $1.Position get ciPosition => $_getN(2);
+  @$pb.TagNumber(5)
+  set ciPosition($1.Position v) { setField(5, v); }
+  @$pb.TagNumber(5)
+  $core.bool hasCiPosition() => $_has(2);
+  @$pb.TagNumber(5)
+  void clearCiPosition() => clearField(5);
+  @$pb.TagNumber(5)
+  $1.Position ensureCiPosition() => $_ensure(2);
+}
+
+class OrienteerGameSaveInfo extends $pb.GeneratedMessage {
+  factory OrienteerGameSaveInfo() => create();
+  OrienteerGameSaveInfo._() : super();
+  factory OrienteerGameSaveInfo.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory OrienteerGameSaveInfo.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'OrienteerGameSaveInfo', package: const $pb.PackageName(_omitMessageNames ? '' : 'toApp.v1'), createEmptyInstance: create)
+    ..aOM<$2.Timestamp>(1, _omitFieldNames ? '' : 'startAt', subBuilder: $2.Timestamp.create)
+    ..aOM<$3.Duration>(2, _omitFieldNames ? '' : 'duration', subBuilder: $3.Duration.create)
+    ..aOM<$1.GameArriveControlPoint>(3, _omitFieldNames ? '' : 'nextControlPoint', protoName: 'nextControlPoint', subBuilder: $1.GameArriveControlPoint.create)
+    ..hasRequiredFields = false
+  ;
+
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  OrienteerGameSaveInfo clone() => OrienteerGameSaveInfo()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  OrienteerGameSaveInfo copyWith(void Function(OrienteerGameSaveInfo) updates) => super.copyWith((message) => updates(message as OrienteerGameSaveInfo)) as OrienteerGameSaveInfo;
+
+  $pb.BuilderInfo get info_ => _i;
+
+  @$core.pragma('dart2js:noInline')
+  static OrienteerGameSaveInfo create() => OrienteerGameSaveInfo._();
+  OrienteerGameSaveInfo createEmptyInstance() => create();
+  static $pb.PbList<OrienteerGameSaveInfo> createRepeated() => $pb.PbList<OrienteerGameSaveInfo>();
+  @$core.pragma('dart2js:noInline')
+  static OrienteerGameSaveInfo getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<OrienteerGameSaveInfo>(create);
+  static OrienteerGameSaveInfo? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $2.Timestamp get startAt => $_getN(0);
+  @$pb.TagNumber(1)
+  set startAt($2.Timestamp v) { setField(1, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasStartAt() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearStartAt() => clearField(1);
+  @$pb.TagNumber(1)
+  $2.Timestamp ensureStartAt() => $_ensure(0);
+
+  @$pb.TagNumber(2)
+  $3.Duration get duration => $_getN(1);
+  @$pb.TagNumber(2)
+  set duration($3.Duration v) { setField(2, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasDuration() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearDuration() => clearField(2);
+  @$pb.TagNumber(2)
+  $3.Duration ensureDuration() => $_ensure(1);
+
+  @$pb.TagNumber(3)
+  $1.GameArriveControlPoint get nextControlPoint => $_getN(2);
+  @$pb.TagNumber(3)
+  set nextControlPoint($1.GameArriveControlPoint v) { setField(3, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasNextControlPoint() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearNextControlPoint() => clearField(3);
+  @$pb.TagNumber(3)
+  $1.GameArriveControlPoint ensureNextControlPoint() => $_ensure(2);
+}
+
+
+const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names');
+const _omitMessageNames = $core.bool.fromEnvironment('protobuf.omit_message_names');

+ 11 - 0
lib/generated/to_app_api.pbenum.dart

@@ -0,0 +1,11 @@
+//
+//  Generated code. Do not modify.
+//  source: to_app_api.proto
+//
+// @dart = 2.12
+
+// ignore_for_file: annotate_overrides, camel_case_types
+// ignore_for_file: constant_identifier_names, library_prefixes
+// ignore_for_file: non_constant_identifier_names, prefer_final_fields
+// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
+

+ 240 - 0
lib/generated/to_app_api.pbgrpc.dart

@@ -0,0 +1,240 @@
+//
+//  Generated code. Do not modify.
+//  source: to_app_api.proto
+//
+// @dart = 2.12
+
+// ignore_for_file: annotate_overrides, camel_case_types
+// ignore_for_file: constant_identifier_names, library_prefixes
+// ignore_for_file: non_constant_identifier_names, prefer_final_fields
+// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
+
+import 'dart:async' as $async;
+import 'dart:core' as $core;
+
+import 'package:grpc/service_api.dart' as $grpc;
+import 'package:protobuf/protobuf.dart' as $pb;
+
+import 'base.pb.dart' as $1;
+import 'to_app_api.pb.dart' as $0;
+
+export 'to_app_api.pb.dart';
+
+@$pb.GrpcServiceName('toApp.v1.ApiToApp')
+class ApiToAppClient extends $grpc.Client {
+  static final _$toSendCodeToPhoneV2 = $grpc.ClientMethod<$0.ToSendCodeToPhoneRequestV2, $1.DefaultReply>(
+      '/toApp.v1.ApiToApp/ToSendCodeToPhoneV2',
+      ($0.ToSendCodeToPhoneRequestV2 value) => value.writeToBuffer(),
+      ($core.List<$core.int> value) => $1.DefaultReply.fromBuffer(value));
+  static final _$toGetSmsSendLeftTimeV2 = $grpc.ClientMethod<$1.GetSmsSendLeftTimeRequest, $1.GetSmsSendLeftTimeReply>(
+      '/toApp.v1.ApiToApp/ToGetSmsSendLeftTimeV2',
+      ($1.GetSmsSendLeftTimeRequest value) => value.writeToBuffer(),
+      ($core.List<$core.int> value) => $1.GetSmsSendLeftTimeReply.fromBuffer(value));
+  static final _$toSignInV2 = $grpc.ClientMethod<$0.ToSignInRequestV2, $1.SignInReply>(
+      '/toApp.v1.ApiToApp/ToSignInV2',
+      ($0.ToSignInRequestV2 value) => value.writeToBuffer(),
+      ($core.List<$core.int> value) => $1.SignInReply.fromBuffer(value));
+  static final _$toSignOutV2 = $grpc.ClientMethod<$1.DefaultRequest, $1.DefaultReply>(
+      '/toApp.v1.ApiToApp/ToSignOutV2',
+      ($1.DefaultRequest value) => value.writeToBuffer(),
+      ($core.List<$core.int> value) => $1.DefaultReply.fromBuffer(value));
+  static final _$toGetServerTime = $grpc.ClientMethod<$1.DefaultRequest, $0.GetServerTimeRp>(
+      '/toApp.v1.ApiToApp/ToGetServerTime',
+      ($1.DefaultRequest value) => value.writeToBuffer(),
+      ($core.List<$core.int> value) => $0.GetServerTimeRp.fromBuffer(value));
+  static final _$toMapListV2 = $grpc.ClientMethod<$0.MapListRequestV2, $0.ToMapListReplyV2>(
+      '/toApp.v1.ApiToApp/ToMapListV2',
+      ($0.MapListRequestV2 value) => value.writeToBuffer(),
+      ($core.List<$core.int> value) => $0.ToMapListReplyV2.fromBuffer(value));
+  static final _$toMapDetailV2 = $grpc.ClientMethod<$1.IdRequest, $0.ToMapInfoV2>(
+      '/toApp.v1.ApiToApp/ToMapDetailV2',
+      ($1.IdRequest value) => value.writeToBuffer(),
+      ($core.List<$core.int> value) => $0.ToMapInfoV2.fromBuffer(value));
+  static final _$toGetBinaryByMd5 = $grpc.ClientMethod<$0.ToGetBinaryByMd5Request, $1.BinaryPartV2>(
+      '/toApp.v1.ApiToApp/ToGetBinaryByMd5',
+      ($0.ToGetBinaryByMd5Request value) => value.writeToBuffer(),
+      ($core.List<$core.int> value) => $1.BinaryPartV2.fromBuffer(value));
+  static final _$toUserDetailQueryV2 = $grpc.ClientMethod<$0.ToUserDetailQueryRequestV2, $0.ToUserDetailQueryReplyV2>(
+      '/toApp.v1.ApiToApp/ToUserDetailQueryV2',
+      ($0.ToUserDetailQueryRequestV2 value) => value.writeToBuffer(),
+      ($core.List<$core.int> value) => $0.ToUserDetailQueryReplyV2.fromBuffer(value));
+  static final _$toRedisTest = $grpc.ClientMethod<$1.DefaultRequest, $0.ToOrienteerInGameInfo>(
+      '/toApp.v1.ApiToApp/ToRedisTest',
+      ($1.DefaultRequest value) => value.writeToBuffer(),
+      ($core.List<$core.int> value) => $0.ToOrienteerInGameInfo.fromBuffer(value));
+
+  ApiToAppClient($grpc.ClientChannel channel,
+      {$grpc.CallOptions? options,
+      $core.Iterable<$grpc.ClientInterceptor>? interceptors})
+      : super(channel, options: options,
+        interceptors: interceptors);
+
+  $grpc.ResponseFuture<$1.DefaultReply> toSendCodeToPhoneV2($0.ToSendCodeToPhoneRequestV2 request, {$grpc.CallOptions? options}) {
+    return $createUnaryCall(_$toSendCodeToPhoneV2, request, options: options);
+  }
+
+  $grpc.ResponseFuture<$1.GetSmsSendLeftTimeReply> toGetSmsSendLeftTimeV2($1.GetSmsSendLeftTimeRequest request, {$grpc.CallOptions? options}) {
+    return $createUnaryCall(_$toGetSmsSendLeftTimeV2, request, options: options);
+  }
+
+  $grpc.ResponseFuture<$1.SignInReply> toSignInV2($0.ToSignInRequestV2 request, {$grpc.CallOptions? options}) {
+    return $createUnaryCall(_$toSignInV2, request, options: options);
+  }
+
+  $grpc.ResponseFuture<$1.DefaultReply> toSignOutV2($1.DefaultRequest request, {$grpc.CallOptions? options}) {
+    return $createUnaryCall(_$toSignOutV2, request, options: options);
+  }
+
+  $grpc.ResponseFuture<$0.GetServerTimeRp> toGetServerTime($1.DefaultRequest request, {$grpc.CallOptions? options}) {
+    return $createUnaryCall(_$toGetServerTime, request, options: options);
+  }
+
+  $grpc.ResponseFuture<$0.ToMapListReplyV2> toMapListV2($0.MapListRequestV2 request, {$grpc.CallOptions? options}) {
+    return $createUnaryCall(_$toMapListV2, request, options: options);
+  }
+
+  $grpc.ResponseFuture<$0.ToMapInfoV2> toMapDetailV2($1.IdRequest request, {$grpc.CallOptions? options}) {
+    return $createUnaryCall(_$toMapDetailV2, request, options: options);
+  }
+
+  $grpc.ResponseStream<$1.BinaryPartV2> toGetBinaryByMd5($0.ToGetBinaryByMd5Request request, {$grpc.CallOptions? options}) {
+    return $createStreamingCall(_$toGetBinaryByMd5, $async.Stream.fromIterable([request]), options: options);
+  }
+
+  $grpc.ResponseFuture<$0.ToUserDetailQueryReplyV2> toUserDetailQueryV2($0.ToUserDetailQueryRequestV2 request, {$grpc.CallOptions? options}) {
+    return $createUnaryCall(_$toUserDetailQueryV2, request, options: options);
+  }
+
+  $grpc.ResponseFuture<$0.ToOrienteerInGameInfo> toRedisTest($1.DefaultRequest request, {$grpc.CallOptions? options}) {
+    return $createUnaryCall(_$toRedisTest, request, options: options);
+  }
+}
+
+@$pb.GrpcServiceName('toApp.v1.ApiToApp')
+abstract class ApiToAppServiceBase extends $grpc.Service {
+  $core.String get $name => 'toApp.v1.ApiToApp';
+
+  ApiToAppServiceBase() {
+    $addMethod($grpc.ServiceMethod<$0.ToSendCodeToPhoneRequestV2, $1.DefaultReply>(
+        'ToSendCodeToPhoneV2',
+        toSendCodeToPhoneV2_Pre,
+        false,
+        false,
+        ($core.List<$core.int> value) => $0.ToSendCodeToPhoneRequestV2.fromBuffer(value),
+        ($1.DefaultReply value) => value.writeToBuffer()));
+    $addMethod($grpc.ServiceMethod<$1.GetSmsSendLeftTimeRequest, $1.GetSmsSendLeftTimeReply>(
+        'ToGetSmsSendLeftTimeV2',
+        toGetSmsSendLeftTimeV2_Pre,
+        false,
+        false,
+        ($core.List<$core.int> value) => $1.GetSmsSendLeftTimeRequest.fromBuffer(value),
+        ($1.GetSmsSendLeftTimeReply value) => value.writeToBuffer()));
+    $addMethod($grpc.ServiceMethod<$0.ToSignInRequestV2, $1.SignInReply>(
+        'ToSignInV2',
+        toSignInV2_Pre,
+        false,
+        false,
+        ($core.List<$core.int> value) => $0.ToSignInRequestV2.fromBuffer(value),
+        ($1.SignInReply value) => value.writeToBuffer()));
+    $addMethod($grpc.ServiceMethod<$1.DefaultRequest, $1.DefaultReply>(
+        'ToSignOutV2',
+        toSignOutV2_Pre,
+        false,
+        false,
+        ($core.List<$core.int> value) => $1.DefaultRequest.fromBuffer(value),
+        ($1.DefaultReply value) => value.writeToBuffer()));
+    $addMethod($grpc.ServiceMethod<$1.DefaultRequest, $0.GetServerTimeRp>(
+        'ToGetServerTime',
+        toGetServerTime_Pre,
+        false,
+        false,
+        ($core.List<$core.int> value) => $1.DefaultRequest.fromBuffer(value),
+        ($0.GetServerTimeRp value) => value.writeToBuffer()));
+    $addMethod($grpc.ServiceMethod<$0.MapListRequestV2, $0.ToMapListReplyV2>(
+        'ToMapListV2',
+        toMapListV2_Pre,
+        false,
+        false,
+        ($core.List<$core.int> value) => $0.MapListRequestV2.fromBuffer(value),
+        ($0.ToMapListReplyV2 value) => value.writeToBuffer()));
+    $addMethod($grpc.ServiceMethod<$1.IdRequest, $0.ToMapInfoV2>(
+        'ToMapDetailV2',
+        toMapDetailV2_Pre,
+        false,
+        false,
+        ($core.List<$core.int> value) => $1.IdRequest.fromBuffer(value),
+        ($0.ToMapInfoV2 value) => value.writeToBuffer()));
+    $addMethod($grpc.ServiceMethod<$0.ToGetBinaryByMd5Request, $1.BinaryPartV2>(
+        'ToGetBinaryByMd5',
+        toGetBinaryByMd5_Pre,
+        false,
+        true,
+        ($core.List<$core.int> value) => $0.ToGetBinaryByMd5Request.fromBuffer(value),
+        ($1.BinaryPartV2 value) => value.writeToBuffer()));
+    $addMethod($grpc.ServiceMethod<$0.ToUserDetailQueryRequestV2, $0.ToUserDetailQueryReplyV2>(
+        'ToUserDetailQueryV2',
+        toUserDetailQueryV2_Pre,
+        false,
+        false,
+        ($core.List<$core.int> value) => $0.ToUserDetailQueryRequestV2.fromBuffer(value),
+        ($0.ToUserDetailQueryReplyV2 value) => value.writeToBuffer()));
+    $addMethod($grpc.ServiceMethod<$1.DefaultRequest, $0.ToOrienteerInGameInfo>(
+        'ToRedisTest',
+        toRedisTest_Pre,
+        false,
+        false,
+        ($core.List<$core.int> value) => $1.DefaultRequest.fromBuffer(value),
+        ($0.ToOrienteerInGameInfo value) => value.writeToBuffer()));
+  }
+
+  $async.Future<$1.DefaultReply> toSendCodeToPhoneV2_Pre($grpc.ServiceCall call, $async.Future<$0.ToSendCodeToPhoneRequestV2> request) async {
+    return toSendCodeToPhoneV2(call, await request);
+  }
+
+  $async.Future<$1.GetSmsSendLeftTimeReply> toGetSmsSendLeftTimeV2_Pre($grpc.ServiceCall call, $async.Future<$1.GetSmsSendLeftTimeRequest> request) async {
+    return toGetSmsSendLeftTimeV2(call, await request);
+  }
+
+  $async.Future<$1.SignInReply> toSignInV2_Pre($grpc.ServiceCall call, $async.Future<$0.ToSignInRequestV2> request) async {
+    return toSignInV2(call, await request);
+  }
+
+  $async.Future<$1.DefaultReply> toSignOutV2_Pre($grpc.ServiceCall call, $async.Future<$1.DefaultRequest> request) async {
+    return toSignOutV2(call, await request);
+  }
+
+  $async.Future<$0.GetServerTimeRp> toGetServerTime_Pre($grpc.ServiceCall call, $async.Future<$1.DefaultRequest> request) async {
+    return toGetServerTime(call, await request);
+  }
+
+  $async.Future<$0.ToMapListReplyV2> toMapListV2_Pre($grpc.ServiceCall call, $async.Future<$0.MapListRequestV2> request) async {
+    return toMapListV2(call, await request);
+  }
+
+  $async.Future<$0.ToMapInfoV2> toMapDetailV2_Pre($grpc.ServiceCall call, $async.Future<$1.IdRequest> request) async {
+    return toMapDetailV2(call, await request);
+  }
+
+  $async.Stream<$1.BinaryPartV2> toGetBinaryByMd5_Pre($grpc.ServiceCall call, $async.Future<$0.ToGetBinaryByMd5Request> request) async* {
+    yield* toGetBinaryByMd5(call, await request);
+  }
+
+  $async.Future<$0.ToUserDetailQueryReplyV2> toUserDetailQueryV2_Pre($grpc.ServiceCall call, $async.Future<$0.ToUserDetailQueryRequestV2> request) async {
+    return toUserDetailQueryV2(call, await request);
+  }
+
+  $async.Future<$0.ToOrienteerInGameInfo> toRedisTest_Pre($grpc.ServiceCall call, $async.Future<$1.DefaultRequest> request) async {
+    return toRedisTest(call, await request);
+  }
+
+  $async.Future<$1.DefaultReply> toSendCodeToPhoneV2($grpc.ServiceCall call, $0.ToSendCodeToPhoneRequestV2 request);
+  $async.Future<$1.GetSmsSendLeftTimeReply> toGetSmsSendLeftTimeV2($grpc.ServiceCall call, $1.GetSmsSendLeftTimeRequest request);
+  $async.Future<$1.SignInReply> toSignInV2($grpc.ServiceCall call, $0.ToSignInRequestV2 request);
+  $async.Future<$1.DefaultReply> toSignOutV2($grpc.ServiceCall call, $1.DefaultRequest request);
+  $async.Future<$0.GetServerTimeRp> toGetServerTime($grpc.ServiceCall call, $1.DefaultRequest request);
+  $async.Future<$0.ToMapListReplyV2> toMapListV2($grpc.ServiceCall call, $0.MapListRequestV2 request);
+  $async.Future<$0.ToMapInfoV2> toMapDetailV2($grpc.ServiceCall call, $1.IdRequest request);
+  $async.Stream<$1.BinaryPartV2> toGetBinaryByMd5($grpc.ServiceCall call, $0.ToGetBinaryByMd5Request request);
+  $async.Future<$0.ToUserDetailQueryReplyV2> toUserDetailQueryV2($grpc.ServiceCall call, $0.ToUserDetailQueryRequestV2 request);
+  $async.Future<$0.ToOrienteerInGameInfo> toRedisTest($grpc.ServiceCall call, $1.DefaultRequest request);
+}

+ 305 - 0
lib/generated/to_app_api.pbjson.dart

@@ -0,0 +1,305 @@
+//
+//  Generated code. Do not modify.
+//  source: to_app_api.proto
+//
+// @dart = 2.12
+
+// ignore_for_file: annotate_overrides, camel_case_types
+// ignore_for_file: constant_identifier_names, library_prefixes
+// ignore_for_file: non_constant_identifier_names, prefer_final_fields
+// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
+
+import 'dart:convert' as $convert;
+import 'dart:core' as $core;
+import 'dart:typed_data' as $typed_data;
+
+@$core.Deprecated('Use toGetBinaryByMd5RequestDescriptor instead')
+const ToGetBinaryByMd5Request$json = {
+  '1': 'ToGetBinaryByMd5Request',
+  '2': [
+    {'1': 'md5', '3': 1, '4': 1, '5': 12, '10': 'md5'},
+  ],
+};
+
+/// Descriptor for `ToGetBinaryByMd5Request`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List toGetBinaryByMd5RequestDescriptor = $convert.base64Decode(
+    'ChdUb0dldEJpbmFyeUJ5TWQ1UmVxdWVzdBIQCgNtZDUYASABKAxSA21kNQ==');
+
+@$core.Deprecated('Use getServerTimeRpDescriptor instead')
+const GetServerTimeRp$json = {
+  '1': 'GetServerTimeRp',
+  '2': [
+    {'1': 'millisecondStamp', '3': 1, '4': 1, '5': 3, '10': 'millisecondStamp'},
+  ],
+};
+
+/// Descriptor for `GetServerTimeRp`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List getServerTimeRpDescriptor = $convert.base64Decode(
+    'Cg9HZXRTZXJ2ZXJUaW1lUnASKgoQbWlsbGlzZWNvbmRTdGFtcBgBIAEoA1IQbWlsbGlzZWNvbm'
+    'RTdGFtcA==');
+
+@$core.Deprecated('Use toSendCodeToPhoneRequestV2Descriptor instead')
+const ToSendCodeToPhoneRequestV2$json = {
+  '1': 'ToSendCodeToPhoneRequestV2',
+  '2': [
+    {'1': 'phone', '3': 1, '4': 1, '5': 9, '10': 'phone'},
+    {'1': 'smsType', '3': 2, '4': 1, '5': 14, '6': '.base.v1.SmsType', '10': 'smsType'},
+  ],
+};
+
+/// Descriptor for `ToSendCodeToPhoneRequestV2`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List toSendCodeToPhoneRequestV2Descriptor = $convert.base64Decode(
+    'ChpUb1NlbmRDb2RlVG9QaG9uZVJlcXVlc3RWMhIUCgVwaG9uZRgBIAEoCVIFcGhvbmUSKgoHc2'
+    '1zVHlwZRgCIAEoDjIQLmJhc2UudjEuU21zVHlwZVIHc21zVHlwZQ==');
+
+@$core.Deprecated('Use toSignInRequestV2Descriptor instead')
+const ToSignInRequestV2$json = {
+  '1': 'ToSignInRequestV2',
+  '2': [
+    {'1': 'userCode', '3': 1, '4': 1, '5': 9, '10': 'userCode'},
+    {'1': 'password', '3': 2, '4': 1, '5': 9, '10': 'password'},
+    {'1': 'ip', '3': 3, '4': 1, '5': 9, '10': 'ip'},
+  ],
+};
+
+/// Descriptor for `ToSignInRequestV2`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List toSignInRequestV2Descriptor = $convert.base64Decode(
+    'ChFUb1NpZ25JblJlcXVlc3RWMhIaCgh1c2VyQ29kZRgBIAEoCVIIdXNlckNvZGUSGgoIcGFzc3'
+    'dvcmQYAiABKAlSCHBhc3N3b3JkEg4KAmlwGAMgASgJUgJpcA==');
+
+@$core.Deprecated('Use mapListRequestV2Descriptor instead')
+const MapListRequestV2$json = {
+  '1': 'MapListRequestV2',
+  '2': [
+    {'1': 'position', '3': 1, '4': 1, '5': 11, '6': '.base.v1.Position', '10': 'position'},
+    {'1': 'offset', '3': 2, '4': 1, '5': 5, '10': 'offset'},
+    {'1': 'limit', '3': 3, '4': 1, '5': 5, '10': 'limit'},
+  ],
+};
+
+/// Descriptor for `MapListRequestV2`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List mapListRequestV2Descriptor = $convert.base64Decode(
+    'ChBNYXBMaXN0UmVxdWVzdFYyEi0KCHBvc2l0aW9uGAEgASgLMhEuYmFzZS52MS5Qb3NpdGlvbl'
+    'IIcG9zaXRpb24SFgoGb2Zmc2V0GAIgASgFUgZvZmZzZXQSFAoFbGltaXQYAyABKAVSBWxpbWl0');
+
+@$core.Deprecated('Use toMapListReplyV2Descriptor instead')
+const ToMapListReplyV2$json = {
+  '1': 'ToMapListReplyV2',
+  '2': [
+    {'1': 'list', '3': 1, '4': 3, '5': 11, '6': '.toApp.v1.ToMapSimpleV2', '10': 'list'},
+  ],
+};
+
+/// Descriptor for `ToMapListReplyV2`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List toMapListReplyV2Descriptor = $convert.base64Decode(
+    'ChBUb01hcExpc3RSZXBseVYyEisKBGxpc3QYASADKAsyFy50b0FwcC52MS5Ub01hcFNpbXBsZV'
+    'YyUgRsaXN0');
+
+@$core.Deprecated('Use toMapSimpleV2Descriptor instead')
+const ToMapSimpleV2$json = {
+  '1': 'ToMapSimpleV2',
+  '2': [
+    {'1': 'mapId', '3': 1, '4': 1, '5': 5, '10': 'mapId'},
+    {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'},
+    {'1': 'mapScaleNumber', '3': 3, '4': 1, '5': 5, '10': 'mapScaleNumber'},
+    {'1': 'description', '3': 4, '4': 1, '5': 9, '10': 'description'},
+    {'1': 'distance', '3': 5, '4': 1, '5': 1, '10': 'distance'},
+    {'1': 'image', '3': 6, '4': 1, '5': 11, '6': '.base.v1.NetImage', '10': 'image'},
+  ],
+};
+
+/// Descriptor for `ToMapSimpleV2`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List toMapSimpleV2Descriptor = $convert.base64Decode(
+    'Cg1Ub01hcFNpbXBsZVYyEhQKBW1hcElkGAEgASgFUgVtYXBJZBISCgRuYW1lGAIgASgJUgRuYW'
+    '1lEiYKDm1hcFNjYWxlTnVtYmVyGAMgASgFUg5tYXBTY2FsZU51bWJlchIgCgtkZXNjcmlwdGlv'
+    'bhgEIAEoCVILZGVzY3JpcHRpb24SGgoIZGlzdGFuY2UYBSABKAFSCGRpc3RhbmNlEicKBWltYW'
+    'dlGAYgASgLMhEuYmFzZS52MS5OZXRJbWFnZVIFaW1hZ2U=');
+
+@$core.Deprecated('Use toMapInfoV2Descriptor instead')
+const ToMapInfoV2$json = {
+  '1': 'ToMapInfoV2',
+  '2': [
+    {'1': 'mapId', '3': 1, '4': 1, '5': 5, '10': 'mapId'},
+    {'1': 'mapName', '3': 2, '4': 1, '5': 9, '10': 'mapName'},
+    {'1': 'zipImage', '3': 3, '4': 1, '5': 11, '6': '.base.v1.NetImage', '10': 'zipImage'},
+  ],
+};
+
+/// Descriptor for `ToMapInfoV2`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List toMapInfoV2Descriptor = $convert.base64Decode(
+    'CgtUb01hcEluZm9WMhIUCgVtYXBJZBgBIAEoBVIFbWFwSWQSGAoHbWFwTmFtZRgCIAEoCVIHbW'
+    'FwTmFtZRItCgh6aXBJbWFnZRgDIAEoCzIRLmJhc2UudjEuTmV0SW1hZ2VSCHppcEltYWdl');
+
+@$core.Deprecated('Use toUserDetailQueryRequestV2Descriptor instead')
+const ToUserDetailQueryRequestV2$json = {
+  '1': 'ToUserDetailQueryRequestV2',
+  '2': [
+    {'1': 'mapId', '3': 1, '4': 1, '5': 5, '10': 'mapId'},
+    {'1': 'isFullQuery', '3': 2, '4': 1, '5': 8, '10': 'isFullQuery'},
+  ],
+};
+
+/// Descriptor for `ToUserDetailQueryRequestV2`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List toUserDetailQueryRequestV2Descriptor = $convert.base64Decode(
+    'ChpUb1VzZXJEZXRhaWxRdWVyeVJlcXVlc3RWMhIUCgVtYXBJZBgBIAEoBVIFbWFwSWQSIAoLaX'
+    'NGdWxsUXVlcnkYAiABKAhSC2lzRnVsbFF1ZXJ5');
+
+@$core.Deprecated('Use toUserDetailQueryReplyV2Descriptor instead')
+const ToUserDetailQueryReplyV2$json = {
+  '1': 'ToUserDetailQueryReplyV2',
+  '2': [
+    {'1': 'list', '3': 1, '4': 3, '5': 11, '6': '.toApp.v1.ToActionInfo', '10': 'list'},
+  ],
+};
+
+/// Descriptor for `ToUserDetailQueryReplyV2`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List toUserDetailQueryReplyV2Descriptor = $convert.base64Decode(
+    'ChhUb1VzZXJEZXRhaWxRdWVyeVJlcGx5VjISKgoEbGlzdBgBIAMoCzIWLnRvQXBwLnYxLlRvQW'
+    'N0aW9uSW5mb1IEbGlzdA==');
+
+@$core.Deprecated('Use toActionInfoDescriptor instead')
+const ToActionInfo$json = {
+  '1': 'ToActionInfo',
+  '2': [
+    {'1': 'actId', '3': 1, '4': 1, '5': 5, '10': 'actId'},
+    {'1': 'actName', '3': 2, '4': 1, '5': 9, '10': 'actName'},
+    {'1': 'totalControlNum', '3': 3, '4': 1, '5': 5, '10': 'totalControlNum'},
+    {'1': 'userList', '3': 4, '4': 3, '5': 11, '6': '.toApp.v1.ToOrienteerInGameInfo', '10': 'userList'},
+  ],
+};
+
+/// Descriptor for `ToActionInfo`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List toActionInfoDescriptor = $convert.base64Decode(
+    'CgxUb0FjdGlvbkluZm8SFAoFYWN0SWQYASABKAVSBWFjdElkEhgKB2FjdE5hbWUYAiABKAlSB2'
+    'FjdE5hbWUSKAoPdG90YWxDb250cm9sTnVtGAMgASgFUg90b3RhbENvbnRyb2xOdW0SOwoIdXNl'
+    'ckxpc3QYBCADKAsyHy50b0FwcC52MS5Ub09yaWVudGVlckluR2FtZUluZm9SCHVzZXJMaXN0');
+
+@$core.Deprecated('Use toOrienteerInGameInfoDescriptor instead')
+const ToOrienteerInGameInfo$json = {
+  '1': 'ToOrienteerInGameInfo',
+  '2': [
+    {'1': 'UserId', '3': 1, '4': 1, '5': 5, '10': 'UserId'},
+    {'1': 'baseInfo', '3': 2, '4': 1, '5': 11, '6': '.toApp.v1.OrienteerBaseInfo', '10': 'baseInfo'},
+    {'1': 'gpsInfo', '3': 3, '4': 1, '5': 11, '6': '.toApp.v1.OrienteerGpsInfo', '10': 'gpsInfo'},
+    {'1': 'hrInfo', '3': 4, '4': 1, '5': 11, '6': '.toApp.v1.OrienteerHrInfo', '10': 'hrInfo'},
+    {'1': 'gameSaveInfo', '3': 5, '4': 1, '5': 11, '6': '.toApp.v1.OrienteerGameSaveInfo', '10': 'gameSaveInfo'},
+    {'1': 'courseBaseInfo', '3': 6, '4': 1, '5': 11, '6': '.toApp.v1.CourseBaseInfo', '10': 'courseBaseInfo'},
+    {'1': 'otherInfo', '3': 7, '4': 1, '5': 11, '6': '.toApp.v1.OrienteerOtherInfo', '10': 'otherInfo'},
+  ],
+};
+
+/// Descriptor for `ToOrienteerInGameInfo`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List toOrienteerInGameInfoDescriptor = $convert.base64Decode(
+    'ChVUb09yaWVudGVlckluR2FtZUluZm8SFgoGVXNlcklkGAEgASgFUgZVc2VySWQSNwoIYmFzZU'
+    'luZm8YAiABKAsyGy50b0FwcC52MS5PcmllbnRlZXJCYXNlSW5mb1IIYmFzZUluZm8SNAoHZ3Bz'
+    'SW5mbxgDIAEoCzIaLnRvQXBwLnYxLk9yaWVudGVlckdwc0luZm9SB2dwc0luZm8SMQoGaHJJbm'
+    'ZvGAQgASgLMhkudG9BcHAudjEuT3JpZW50ZWVySHJJbmZvUgZockluZm8SQwoMZ2FtZVNhdmVJ'
+    'bmZvGAUgASgLMh8udG9BcHAudjEuT3JpZW50ZWVyR2FtZVNhdmVJbmZvUgxnYW1lU2F2ZUluZm'
+    '8SQAoOY291cnNlQmFzZUluZm8YBiABKAsyGC50b0FwcC52MS5Db3Vyc2VCYXNlSW5mb1IOY291'
+    'cnNlQmFzZUluZm8SOgoJb3RoZXJJbmZvGAcgASgLMhwudG9BcHAudjEuT3JpZW50ZWVyT3RoZX'
+    'JJbmZvUglvdGhlckluZm8=');
+
+@$core.Deprecated('Use orienteerBaseInfoDescriptor instead')
+const OrienteerBaseInfo$json = {
+  '1': 'OrienteerBaseInfo',
+  '2': [
+    {'1': 'Name', '3': 1, '4': 1, '5': 9, '10': 'Name'},
+    {'1': 'Phone', '3': 2, '4': 1, '5': 9, '10': 'Phone'},
+    {'1': 'HeadUrl', '3': 3, '4': 1, '5': 9, '10': 'HeadUrl'},
+  ],
+};
+
+/// Descriptor for `OrienteerBaseInfo`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List orienteerBaseInfoDescriptor = $convert.base64Decode(
+    'ChFPcmllbnRlZXJCYXNlSW5mbxISCgROYW1lGAEgASgJUgROYW1lEhQKBVBob25lGAIgASgJUg'
+    'VQaG9uZRIYCgdIZWFkVXJsGAMgASgJUgdIZWFkVXJs');
+
+@$core.Deprecated('Use orienteerGpsInfoDescriptor instead')
+const OrienteerGpsInfo$json = {
+  '1': 'OrienteerGpsInfo',
+  '2': [
+    {'1': 'gameGpsInfos', '3': 1, '4': 3, '5': 11, '6': '.base.v1.GameGpsInfo', '10': 'gameGpsInfos'},
+    {'1': 'Distance', '3': 2, '4': 1, '5': 5, '10': 'Distance'},
+    {'1': 'Pace', '3': 3, '4': 1, '5': 5, '10': 'Pace'},
+  ],
+};
+
+/// Descriptor for `OrienteerGpsInfo`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List orienteerGpsInfoDescriptor = $convert.base64Decode(
+    'ChBPcmllbnRlZXJHcHNJbmZvEjgKDGdhbWVHcHNJbmZvcxgBIAMoCzIULmJhc2UudjEuR2FtZU'
+    'dwc0luZm9SDGdhbWVHcHNJbmZvcxIaCghEaXN0YW5jZRgCIAEoBVIIRGlzdGFuY2USEgoEUGFj'
+    'ZRgDIAEoBVIEUGFjZQ==');
+
+@$core.Deprecated('Use orienteerHrInfoDescriptor instead')
+const OrienteerHrInfo$json = {
+  '1': 'OrienteerHrInfo',
+  '2': [
+    {'1': 'hrInfo', '3': 1, '4': 3, '5': 11, '6': '.base.v1.HeartRate', '10': 'hrInfo'},
+  ],
+};
+
+/// Descriptor for `OrienteerHrInfo`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List orienteerHrInfoDescriptor = $convert.base64Decode(
+    'Cg9PcmllbnRlZXJIckluZm8SKgoGaHJJbmZvGAEgAygLMhIuYmFzZS52MS5IZWFydFJhdGVSBm'
+    'hySW5mbw==');
+
+@$core.Deprecated('Use orienteerOtherInfoDescriptor instead')
+const OrienteerOtherInfo$json = {
+  '1': 'OrienteerOtherInfo',
+  '2': [
+    {'1': 'StepNum', '3': 1, '4': 1, '5': 5, '10': 'StepNum'},
+  ],
+};
+
+/// Descriptor for `OrienteerOtherInfo`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List orienteerOtherInfoDescriptor = $convert.base64Decode(
+    'ChJPcmllbnRlZXJPdGhlckluZm8SGAoHU3RlcE51bRgBIAEoBVIHU3RlcE51bQ==');
+
+@$core.Deprecated('Use courseBaseInfoDescriptor instead')
+const CourseBaseInfo$json = {
+  '1': 'CourseBaseInfo',
+  '2': [
+    {'1': 'CourseId', '3': 1, '4': 1, '5': 5, '10': 'CourseId'},
+    {'1': 'CourseName', '3': 2, '4': 1, '5': 9, '10': 'CourseName'},
+    {'1': 'controlPointSortedList', '3': 3, '4': 3, '5': 11, '6': '.toApp.v1.ToControlPoint', '10': 'controlPointSortedList'},
+  ],
+};
+
+/// Descriptor for `CourseBaseInfo`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List courseBaseInfoDescriptor = $convert.base64Decode(
+    'Cg5Db3Vyc2VCYXNlSW5mbxIaCghDb3Vyc2VJZBgBIAEoBVIIQ291cnNlSWQSHgoKQ291cnNlTm'
+    'FtZRgCIAEoCVIKQ291cnNlTmFtZRJQChZjb250cm9sUG9pbnRTb3J0ZWRMaXN0GAMgAygLMhgu'
+    'dG9BcHAudjEuVG9Db250cm9sUG9pbnRSFmNvbnRyb2xQb2ludFNvcnRlZExpc3Q=');
+
+@$core.Deprecated('Use toControlPointDescriptor instead')
+const ToControlPoint$json = {
+  '1': 'ToControlPoint',
+  '2': [
+    {'1': 'id', '3': 1, '4': 1, '5': 3, '10': 'id'},
+    {'1': 'sn', '3': 2, '4': 1, '5': 9, '10': 'sn'},
+    {'1': 'ciPosition', '3': 5, '4': 1, '5': 11, '6': '.base.v1.Position', '10': 'ciPosition'},
+  ],
+};
+
+/// Descriptor for `ToControlPoint`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List toControlPointDescriptor = $convert.base64Decode(
+    'Cg5Ub0NvbnRyb2xQb2ludBIOCgJpZBgBIAEoA1ICaWQSDgoCc24YAiABKAlSAnNuEjEKCmNpUG'
+    '9zaXRpb24YBSABKAsyES5iYXNlLnYxLlBvc2l0aW9uUgpjaVBvc2l0aW9u');
+
+@$core.Deprecated('Use orienteerGameSaveInfoDescriptor instead')
+const OrienteerGameSaveInfo$json = {
+  '1': 'OrienteerGameSaveInfo',
+  '2': [
+    {'1': 'start_at', '3': 1, '4': 1, '5': 11, '6': '.google.protobuf.Timestamp', '10': 'startAt'},
+    {'1': 'duration', '3': 2, '4': 1, '5': 11, '6': '.google.protobuf.Duration', '10': 'duration'},
+    {'1': 'nextControlPoint', '3': 3, '4': 1, '5': 11, '6': '.base.v1.GameArriveControlPoint', '10': 'nextControlPoint'},
+  ],
+};
+
+/// Descriptor for `OrienteerGameSaveInfo`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List orienteerGameSaveInfoDescriptor = $convert.base64Decode(
+    'ChVPcmllbnRlZXJHYW1lU2F2ZUluZm8SNQoIc3RhcnRfYXQYASABKAsyGi5nb29nbGUucHJvdG'
+    '9idWYuVGltZXN0YW1wUgdzdGFydEF0EjUKCGR1cmF0aW9uGAIgASgLMhkuZ29vZ2xlLnByb3Rv'
+    'YnVmLkR1cmF0aW9uUghkdXJhdGlvbhJLChBuZXh0Q29udHJvbFBvaW50GAMgASgLMh8uYmFzZS'
+    '52MS5HYW1lQXJyaXZlQ29udHJvbFBvaW50UhBuZXh0Q29udHJvbFBvaW50');
+

+ 0 - 0
lib/model/game_person_data.dart → lib/model/__game_person_data.dart.bk


+ 0 - 0
lib/model/project.dart → lib/model/__project.dart.bk


+ 0 - 0
lib/model/provider.dart → lib/model/__provider.dart.bk


+ 0 - 0
lib/model/settlement.dart → lib/model/__settlement.dart.bk


+ 22 - 22
lib/model/game_state.dart

@@ -14,9 +14,9 @@ class GameStateData {
   GameState toState() {
   GameState toState() {
     return GameState()
     return GameState()
       ..name = name
       ..name = name
-      ..timeLocalServerDiff = Duration(microseconds: timeLocalServerDiffMicro)
-      ..pbGameData = pb.GameData.fromBuffer(pbGameData)
-      ..pbGameSave = pb.GameSave.fromBuffer(pbGameSave);
+      ..timeLocalServerDiff = Duration(microseconds: timeLocalServerDiffMicro);
+      // ..pbGameData = pb.GameData.fromBuffer(pbGameData)
+      // ..pbGameSave = pb.GameSave.fromBuffer(pbGameSave);
   }
   }
 
 
   int timeLocalServerDiffMicro = 0;
   int timeLocalServerDiffMicro = 0;
@@ -24,30 +24,30 @@ class GameStateData {
 
 
 class GameState {
 class GameState {
   String name = '';
   String name = '';
-  pb.GameData pbGameData = pb.GameData();
-  pb.GameSave pbGameSave = pb.GameSave();
+  // pb.GameData pbGameData = pb.GameData();
+  // pb.GameSave pbGameSave = pb.GameSave();
   Duration timeLocalServerDiff = 0.seconds;
   Duration timeLocalServerDiff = 0.seconds;
-  DateTime get createTime => pbGameData.gameStart.toDateTime().toLocal();
+  DateTime get createTime => DateTime.now(); //pbGameData.gameStart.toDateTime().toLocal();
 
 
   GameStateData get data {
   GameStateData get data {
     return GameStateData()
     return GameStateData()
       ..name = name
       ..name = name
-      ..timeLocalServerDiffMicro = timeLocalServerDiff.inMicroseconds
-      ..pbGameData = pbGameData.writeToBuffer()
-      ..pbGameSave = pbGameSave.writeToBuffer();
+      ..timeLocalServerDiffMicro = timeLocalServerDiff.inMicroseconds;
+      // ..pbGameData = pbGameData.writeToBuffer()
+      // ..pbGameSave = pbGameSave.writeToBuffer();
   }
   }
 }
 }
 
 
-extension GameDataExtension on pb.GameData {
-  GameState toGameState() {
-    final save = pb.GameSave()
-      ..gameId=gameId;
-    final localNow = DateTime.now();
-    final serverNow = gameStart.toDateTime();
-
-    return GameState()
-      ..timeLocalServerDiff = localNow.difference(serverNow)
-      ..pbGameData = this
-      ..pbGameSave = save;
-  }
-}
+// extension GameDataExtension on pb.GameData {
+//   GameState toGameState() {
+//     final save = pb.GameSave()
+//       ..gameId=gameId;
+//     final localNow = DateTime.now();
+//     final serverNow = gameStart.toDateTime();
+//
+//     return GameState()
+//       ..timeLocalServerDiff = localNow.difference(serverNow)
+//       ..pbGameData = this
+//       ..pbGameSave = save;
+//   }
+// }

+ 659 - 0
lib/service/api.dart.bk

@@ -0,0 +1,659 @@
+import 'dart:math';
+import 'dart:typed_data';
+import 'package:grpc/grpc.dart';
+import 'package:fixnum/fixnum.dart' as fixnum;
+import 'package:trackoffical_app/model.dart';
+import 'package:trackoffical_app/service/app.dart';
+import 'package:trackoffical_app/pb.dart' as pb;
+import 'package:trackoffical_app/service/service.dart';
+import 'package:trackoffical_app/utils.dart';
+import 'package:protobuf/protobuf.dart';
+import '../logger.dart';
+import '../global.dart';
+
+class _Stub{
+  _Stub(
+      this.channel,
+      this.stub
+      );
+  ClientChannel channel;
+  pb.ApiToAppClient stub;
+}
+
+class ApiService extends IService {
+  static ApiService get to => Get.find();
+  ClientChannel? channel;
+
+  String? get token {
+    final out = App.to.userProfile.token.val;
+    if (out.isEmpty) {
+      return null;
+    }
+    return out;
+  }
+
+  set token(String? v) {
+    App.to.userProfile.token.val = v ?? '';
+  }
+
+  String get _appVersion => App.to.appVersion;
+
+  ClientChannel _newChannel(){
+    return ClientChannel(
+      GlobalVar.apiHost,
+      port: GlobalVar.apiPort,
+      options: const ChannelOptions(credentials: ChannelCredentials.secure()),
+    );
+  }
+
+  pb.ApiToAppClient _getStub({Duration? timeout, ClientChannel? channel}){
+    if (this.channel == null) {
+      throw Exception('$runtimeType 未初始化');
+    }
+    final metadata = <String, String>{
+      'source': "${pb.LoginSource.UserApp.value}"
+    };
+    metadata['version'] = _appVersion;
+    if (token != null) {
+      metadata['token'] = token!;
+    }
+
+    return pb.ApiToAppClient(channel??this.channel!,
+        options: CallOptions(
+          metadata: metadata,
+          timeout: timeout,
+        ));
+  }
+
+  pb.ApiToAppClient get stub {
+    return _getStub(timeout: 10.seconds);
+  }
+  _Stub get _stubForStream {
+    final ch = _newChannel();
+    return _Stub(ch, _getStub(channel: ch)) ;
+  }
+
+
+  Future<void> syncTime()async{
+    try{
+      final serverNow = await serverTime();
+      App.to.correctByServerNow(serverNow);
+      info('服务器时间:${App.to.now}');
+    }catch(e){
+      warn("获取服务器时间失败: ", e);
+    }
+  }
+
+
+  @override
+  Future<ApiService> init() async {
+    channel = _newChannel();
+    syncTime();
+
+    return this;
+  }
+
+  Future<bool> isSignIn() async {
+    final token = this.token;
+    if (token == null) {
+      return false;
+    }
+    if (token.isNotEmpty) {
+      try {
+        await flushUserInfo();
+      } catch (e) {
+        return false;
+      }
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+
+  Future<void> getVfCode() async {
+    await stub.getVfPic(pb.DefaultRequest());
+  }
+
+  Future<void> authSendCodeToPhone(String phone, pb.SmsType smsType)async{
+    info('authSendCodeToPhone [$phone]');
+    await stub.authSendCodeToPhone(pb.AuthSendCodeToPhoneRequest()
+      ..phone= phone
+      ..userType= pb.UserType.AppUser
+        ..smsType= smsType
+    );
+  }
+
+  Future<void> signUp(String phone, String code, String? name, pb.User_Sex sex)async{
+    info('signUp [$phone]');
+    var r =  await stub.signUp(pb.SignUpRequest()
+      ..phone= phone
+      ..password= code
+      ..nickname= name??''
+      ..userType= pb.UserType.AppUser
+      ..sex= sex
+    );
+    token = r.token;
+  }
+
+  Future<void> signIn(String name, String password) async {
+    final r = await stub.signIn(pb.SignInRequest()
+      ..name = name
+      ..password = password
+    );
+    token = r.token;
+
+    debug('sign in success: $token');
+  }
+
+  void signOut(){
+    stub.signOut(pb.SignOutRequest());
+    token = null;
+  }
+
+  Future<pb.GameData> gameStart(
+    int actId,
+    fixnum.Int64 courseId,
+  ) async {
+    await syncTime();
+
+    final r = await stub.gameStart(pb.GameStartRequest()
+          ..actId= fixnum.Int64(actId)
+          ..courseId= courseId
+          ..hrBand= pb.HrBandType.UseHrBand
+        );
+
+    return r.gameData;
+  }
+
+  Future<void> gameSaveUpload(pb.GameSaveUploadRequest save) async {
+    info('gameSaveUpload');
+    final save2 = save.deepCopy();
+    save2.gameSave.gameHrInfos.clear();
+    save2.gameSave.gameGpsInfos.clear();
+
+    await stub.gameSaveUpload(save2);
+    return;
+  }
+
+
+  Future<pb.ActivityListReply> activityList({
+        MPosition? position
+  }) async {
+    info('call providerList $position');
+    final req = pb.PositionRequest();
+    if(position!= null){
+      req.position=position.toPb();
+    }
+
+    final r = await stub.activityList(req);
+    return r;
+  }
+
+  Future<pb.ActivityDetailReply> activityDetail(int id) async {
+    debug('call activityDetail $id');
+    final r =
+    await  stub.activityDetail(pb.IdRequest()..id= fixnum.Int64(id));
+    return r;
+  }
+
+  Future<void> flushUserInfo()async{
+    info('flushUserInfo');
+    final r = await stub.myUserQuery(pb.DefaultRequest());
+    final userProfile = App.to.userProfile;
+    userProfile.username.value = r.name;
+    userProfile.head.value = r.head.toModel();
+    userProfile.sex = r.sex.toModel();
+    userProfile.age.val = App.to.now.year - r.birthdayYear;
+    userProfile.heightCm.val = r.heightMillimeter / 10;
+    userProfile.weightKg.val = r.weightGram / 1000;
+    userProfile.rhr.val = r.staticHr;
+  }
+
+  Future<void> _userInfoEdit(
+      String nickName,
+      Sex sex,
+      int birthdayYear,
+      double heightCm,
+      double weightKg,
+      int rhr,
+      ){
+    return stub.userInfoEdit(pb.UserInfoEditRequest()
+      ..nickName=         nickName
+      ..sex=              sex.toPb()
+      ..birthdayYear=     birthdayYear
+      ..heightMillimeter= (heightCm * 10).toInt()
+      ..weightGram=      (weightKg*1000).toInt()
+      ..staticHr =        rhr
+    );
+  }
+  Future<void> saveUserInfo(){
+    App app = Get.find();
+    final userProfile = app.userProfile;
+    return _userInfoEdit(
+        userProfile.username.value,
+        userProfile.sex,
+        app.now.year - userProfile.age.val,
+        userProfile.heightCm.val,
+        userProfile.weightKg.val,
+        userProfile.rhr.val);
+  }
+
+  Future<pb.MyHistoryGameReply> gameHistory({
+    required pb.GameState state,
+    required int offset,
+    required int limit,
+  })async{
+
+    return await stub.myHistoryGame(pb.MyHistoryGameRequest()
+        ..state= state
+        ..offset= offset
+        ..limit=limit
+    );
+  }
+  Future<void> gameHistoryDel(fixnum.Int64 id){
+    return stub.historyGameDel(pb.IdRequest()..id= id);
+  }
+
+  Future<void> closeAccount()async{
+    await stub.unsubscribe(pb.DefaultRequest());
+  }
+
+  Future<void> gameGpsUpload(
+      fixnum.Int64 gameId,
+      List<MPosition> data,
+      int distanceMeter,
+      int paceSecond,
+      ){
+    info('gameGpsUpload');
+    List<pb.GameGpsInfo> l = data.map((p) => p.toPb2()).toList();
+    final req =  pb.GameGpsUploadRequest()
+      ..gameId= gameId.toInt()
+      ..distance= distanceMeter
+      ..pace= paceSecond
+      ..gameGpsInfos.addAll(l);
+
+
+    return stub.gameGpsUpload(req);
+  }
+  Future<void> gameHrUpload(
+      fixnum.Int64 gameId,
+      List<pb.HeartRate> data,
+      ){
+    info('gameHrUpload');
+    return stub.gameHrUpload(pb.GameHrUploadRequest()
+      ..gameId= gameId.toInt()
+      ..gameHrInfos.addAll(data)
+    );
+  }
+  Future<void> gameExerciseStateUpload(
+      fixnum.Int64 gameId,
+      int  avgHr,
+      int  maxHr,
+      /// 单位卡,不是千卡
+      int  cle,
+      double  ck,
+      double  ei,
+      int stepCount,
+      // %
+      int heartRatePercent
+      ){
+    info('gameExerciseStateUpload');
+    return stub.gameCleUpload(pb.GameCleUploadRequest()
+      ..gameId= gameId.toInt()
+      ..avgHr= avgHr
+      ..maxHr= maxHr
+      ..cle=   cle
+      ..ck= ck.round()
+      ..  ei= ei
+      ..stepNum= stepCount
+      ..heartRatePercent= heartRatePercent
+    );
+  }
+
+  @override
+  void onClose() {
+    channel?.shutdown();
+  }
+
+  Future<DateTime> serverTime() async {
+    final begin = DateTime.now();
+    final r = await stub.getServerTime(pb.DefaultRequest());
+    final cost = DateTime.now().difference(begin);
+    final serverNow = DateTime.fromMillisecondsSinceEpoch(
+            r.millisecondStamp.toInt(),
+            isUtc: true)
+        .toLocal();
+    return serverNow.add(cost);
+  }
+
+  Future<String> getRegionCode() async{
+    final r =await stub.getRegion(pb.DefaultRequest());
+    info('位置:${r.name}');
+    return r.code;
+  }
+
+  Future<List<pb.Region>> getRegionList() async{
+    info('getRegionList');
+    final r =await stub.regionList(pb.RegionListRequest()..countryCode= "CN");
+    final list = r.region;
+    return list;
+  }
+
+  Future<Duration> getSmsSendLeftTime(String phone)async{
+    final r = await stub.getSmsSendLeftTime(pb.GetSmsSendLeftTimeRequest()..phone= phone);
+    info('getSmsSendLeftTime: $phone - ${r.second}s');
+    return r.second.seconds;
+  }
+
+  Future<pb.GetUpdateVersionReply> getUpdateVersion(String version)async{
+    info('getUpdateVersion: $version');
+    final r = await stub.getUpdateVersion(pb.GetUpdateVersionRequest()..vCode= version);
+    return r;
+  }
+
+  Future<pb.GameDetailReply> getGameHistoryDetail(fixnum.Int64 id)async{
+    info('getGameHistoryDetail: $id');
+    return await stub.historyGameDetail(id.toIdRequest());
+  }
+
+  Future<pb.GameDetailReply> gameFinish(fixnum.Int64 id, bool isDrop)async{
+    info('gameFinish: $id , isDrop: $isDrop');
+    return await stub.gameFinish(pb.GameFinishRequest()..gameId= id.toInt().. isDrop= isDrop);
+  }
+
+  Future<pb.GetInGameDataReply> getInGameData()async{
+    info('getInGameData');
+    return await stub.getInGameData(pb.DefaultRequest());
+  }
+
+  Future<List<pb.CareTakerInfo>> guardianList()async{
+    info('guardianList');
+    final r = await stub.myCareTakerQuery(pb.DefaultRequest());
+    return r.list;
+  }
+  Future<List<pb.MyPupil>> underGuardianList()async{
+    info('underGuardianList');
+    final r = await stub.myPupilListQuery(pb.DefaultRequest());
+    return r.list;
+  }
+
+  Future<void> guardianAdd(String phone, String memo)async{
+    info('guardianAdd: $phone');
+    await stub.myCareTakerAdd(pb.CareTakerInfo()
+      ..cPhone= phone
+      ..memo= memo
+    );
+    return;
+  }
+  Future<void> guardianDel(pb.CareTakerInfo v)async{
+    info('guardianAdd: ${v.crId}');
+    await stub.myCareTakerDel(v.crId.toIdRequest());
+    return;
+  }
+
+  Future<List<MapInfo>> mapRecommendList(MPosition? position)async{
+    info('mapRecommendList: $position');
+    final req = pb.PositionRequest();
+    if(position!= null){
+      req.position=position.toPb();
+    }
+
+    final r = await stub.mapRecommendList(req);
+    return r.mapList.map((e) => e.toModel()..isRecommend=true).toList();
+  }
+  Future<List<MapInfo>> mapList(MPosition? position, int offset, int limit)async{
+    info('mapList: $position');
+    final req = pb.MapListRequest()
+      ..offset=offset
+      ..limit=limit;
+    if(position!= null){
+      req.position=position.toPb();
+    }
+
+    final r = await stub.mapList(req);
+    return r.mapList.map((e) => e.toModel()).toList();
+  }
+
+  StreamGuardianWatch guardianWatch(int id){
+    info('guardianWatch: $id');
+    final stub = _stubForStream;
+    final stream = stub.stub.pupilInGameWatch(id.toIdRequest());
+
+    return StreamGuardianWatch(stub.channel, stream);
+  }
+
+  Future<Bin> getBinByMd5(Uint8List md5, OnPercentage onPercentage)async{
+    final stream = _getStub().getBinaryByMd5(pb.GetBinaryByMd5Request()..md5= md5);
+    String ext='';
+    Uint8List? data;
+    var nonce=Uint8List(0);
+    var i = 0;
+
+    await for (var one in stream){
+      if(data == null){
+        data = Uint8List(one.allCount);
+        ext = one.ext;
+        nonce= Uint8List.fromList(one.nonce);
+      }
+
+      for(var b in one.data){
+        data[i]=b;
+        i++;
+      }
+
+      onPercentage(i, data.length);
+    }
+
+
+    await stream.cancel();
+    return Bin()
+      ..ext=ext
+      ..data=data??Uint8List(0)
+      ..nonce=nonce;
+  }
+
+
+  Future<void> userHeadEdit(String ext, Uint8List data)async{
+    await stub.userHeadEdit(pb.Image()..ext= ext ..data= data);
+  }
+
+  Future<pb.MapActivityListReply> mapActivityList(int mapId, String pin)async{
+    info('mapActivityList mapId: $mapId pin: $pin');
+
+    final r = await stub.mapActivityList(pb.MapActivityListRequest()
+      ..id= mapId
+      ..pinCode= pin.trim()
+    );
+    return r;
+  }
+  Future<pb.MapActivityListReply> pinCodeActivityList(String pin)async{
+    info('pinCodeActivityList  pin: $pin');
+    final r = await stub.pinCodeActivityList(pb.PinCodeActivityListRequest()
+       .. pinCode= pin.trim()
+    );
+    return r;
+  }
+
+}
+class Bin{
+  var ext='';
+  var data=Uint8List(0);
+  var nonce=Uint8List(0);
+}
+
+typedef OnPercentage = void Function(int, int);
+
+class ApiServiceMock extends ApiService {
+  @override
+  Future<ApiService> init() async {
+    debug('$runtimeType ready!');
+    return this;
+  }
+
+  final random = Random();
+
+  @override
+  Future<void> signIn(String name, String password) async {}
+
+  @override
+  Future<pb.GameData> gameStart(
+      int projectId, fixnum.Int64 mapRouteId) async {
+    info('gameStart Mock');
+    final data = pb.GameData();
+
+    final p1 = pb.ControlPoint()
+      ..id= fixnum.Int64(1)
+      ..info = pb.ControlPointInfo();
+    final p2 = pb.ControlPoint()..id= fixnum.Int64(2)
+      ..info = pb.ControlPointInfo();
+    p1.nfcIdList.add('0465be121c1291');
+    p2.nfcIdList.add('0465bd121c1291');
+
+    data.controlPointSortedList.addAll([p1, p2]);
+
+    data.mapZip = pb.NetImage()
+        ..url=
+            'https://p3.itc.cn/q_70/images03/20210317/94c7636527d042d8a7c9ed08529cc8b2.jpeg'
+        ..md5= [1, 1, 1];
+
+    data.maxDuration = pb.Duration()..seconds= fixnum.Int64(60) * 60;
+    return data;
+  }
+
+
+  @override
+  Future<void> gameSaveUpload(pb.GameSaveUploadRequest save) async {
+    return;
+  }
+
+
+  @override
+  void onReady() {}
+
+  @override
+  void onClose() {}
+
+  @override
+  Future<DateTime> serverTime() async {
+    return DateTime.now();
+  }
+
+  @override
+  Future<pb.MapActivityListReply> mapActivityList(int mapId, String pin)async{
+    return pb.MapActivityListReply()
+      ..list.addAll([
+        pb.MapActivitySimpleInfo()
+          ..id=0
+          ..name= '穿越荒野:勇闯野性之旅-穿越荒野:勇闯野性之旅-穿越荒野:勇闯野性之旅-穿越荒野:勇闯野性之旅-穿越荒野:勇闯野性之旅'
+          ..difficulty= 1
+          ..distanceMinMeter= 217.1
+          ..closeDoorTime= 190.minutes.toPb()
+          ..isUsed= false
+          ..routeCount= 28
+          ..totalControlNum= 12
+        ,
+        pb.MapActivitySimpleInfo()
+          ..id=1
+          ..name= '极限挑战 战胜重力'
+          ..difficulty= 2
+          ..distanceMinMeter= 8.1
+          ..closeDoorTime= 190.minutes.toPb()
+          ..isUsed= true
+          ..routeCount= 6
+          ..totalControlNum= 16
+        ,
+      ])
+    ;
+  }
+  @override
+  Future<pb.ActivityDetailReply> activityDetail(int id) async {
+    final simple = pb.MapActivitySimpleInfo()
+      ..id= 1
+      ..name= '周末爬山健身运动'
+      ..closeDoorTime= 90.minutes.toPb()
+      ..distanceMinMeter= 71.3;
+
+    return pb.ActivityDetailReply()
+      ..baseInfoV2= simple
+      ..content= '    此主题为全民爬山健身定向运动,全民爬山健身运动是我国体育事业发展的重要组成部分,也是实现中华民族伟大复兴中国梦的重要内容。'
+        ..routes.addAll([
+          pb.MapRoute()
+            ..name='XL0002'
+            ..distanceMeter= 3331
+            ..altitudeDiffMeter= 223
+            ..useCount= 0
+          ,
+          pb.MapRoute()
+            ..name= 'XL0003'
+            ..distanceMeter= 5430
+            ..altitudeDiffMeter= 123
+            ..useCount=2
+          ,
+        ])
+    ;
+  }
+
+
+  @override
+  Future<List<MapInfo>> mapRecommendList(MPosition? position)async{
+    info('mapRecommendList: $position');
+
+    return [
+      MapInfo()
+        ..name= '英雄山风景区'
+        ..isOpen=true
+        ..isRecommend=true
+      ,
+      MapInfo()..name= '板桥广场'
+        ..isRecommend=true
+    ];
+  }
+  @override
+  Future<List<MapInfo>> mapList(MPosition? position, int offset, int limit)async{
+    info('mapList: $position');
+
+    final out = <MapInfo>[];
+    for(var i=0;i< limit;i++){
+      out.add(MapInfo()
+          ..name ='$offset-${random.nextInt(10000)}公园'
+      );
+    }
+
+
+    return out;
+  }
+  @override
+  Future<String> getRegionCode() async{
+    return 'test';
+  }
+
+  @override
+  Future<List<pb.Region>> getRegionList() async{
+    info('getRegionList');
+    return [];
+  }
+}
+
+class StreamGuardianWatch{
+  StreamGuardianWatch(
+      this.channel,
+      this.stream
+      );
+
+  ClientChannel channel;
+  ResponseStream<pb.PupilInGameWatchReply> stream;
+
+}
+extension ExtInt64 on fixnum.Int64{
+  pb.IdRequest toIdRequest(){
+    return pb.IdRequest()
+      ..id=this;
+  }
+}
+extension ExtNum on num{
+  pb.IdRequest toIdRequest(){
+    return pb.IdRequest()
+      ..id=fixnum.Int64(toInt());
+  }
+}

+ 1 - 1
lib/service/game/game.dart → lib/service/game/game.dart.bk

@@ -512,7 +512,7 @@ class GameService extends GetxService {
     _loadProgress.value = 0;
     _loadProgress.value = 0;
     status = GameStatus.loading;
     status = GameStatus.loading;
     _app.userProfile.cleanGameSettingsLock();
     _app.userProfile.cleanGameSettingsLock();
-    _app.userProfile.gameSettingsLoadLock(gameState.pbGameData.ruleList);
+    // _app.userProfile.gameSettingsLoadLock(gameState.pbGameData.ruleList);
 
 
     /// 游戏规则
     /// 游戏规则
     // rule = RuleInOrder();
     // rule = RuleInOrder();

+ 0 - 0
lib/service/game/game_instance_guardian.dart → lib/service/game/game_instance_guardian.dart.bk


+ 1 - 1
lib/service/game/game_instance_std/game_instance_std.dart → lib/service/game/game_instance_std/game_instance_std.dart.bk

@@ -380,7 +380,7 @@ class GameInstanceStd extends GameInstance {
     await _saveToDatabase();
     await _saveToDatabase();
     // ---- 载入服务器游戏设置 ----
     // ---- 载入服务器游戏设置 ----
     _app.userProfile.cleanGameSettingsLock();
     _app.userProfile.cleanGameSettingsLock();
-    _app.userProfile.gameSettingsLoadLock(gameState.pbGameData.ruleList);
+    // _app.userProfile.gameSettingsLoadLock(gameState.pbGameData.ruleList);
     // ---- 载入服务器游戏设置 ----
     // ---- 载入服务器游戏设置 ----
 
 
     // 游戏规则
     // 游戏规则

+ 0 - 0
lib/service/game/game_instance_std/plug_location.dart → lib/service/game/game_instance_std/plug_location.dart.bk


+ 0 - 0
lib/service/game/game_instance_std/plug_orientation.dart → lib/service/game/game_instance_std/plug_orientation.dart.bk


+ 0 - 0
lib/service/game/game_instance_std/plug_sport_wear.dart → lib/service/game/game_instance_std/plug_sport_wear.dart.bk


+ 0 - 0
lib/service/game/game_manager_service.dart → lib/service/game/game_manager_service.dart.bk


+ 1 - 1
lib/service/game/map_status.dart → lib/service/game/map_status.dart.bk

@@ -6,7 +6,7 @@ import 'package:get/get.dart';
 import 'package:trackoffical_app/logger.dart';
 import 'package:trackoffical_app/logger.dart';
 import 'package:trackoffical_app/model/game_map.dart';
 import 'package:trackoffical_app/model/game_map.dart';
 import 'package:trackoffical_app/service/app.dart';
 import 'package:trackoffical_app/service/app.dart';
-import 'package:trackoffical_app/service/game/game_model.dart';
+// import 'package:trackoffical_app/service/game/game_model.dart';
 import 'package:vibration/vibration.dart';
 import 'package:vibration/vibration.dart';
 import '../../model/map_mode.dart';
 import '../../model/map_mode.dart';
 import '../../widget/matrix_gesture_detector.dart';
 import '../../widget/matrix_gesture_detector.dart';

+ 0 - 0
lib/service/game/plug_location.dart → lib/service/game/plug_location.dart.bk


+ 0 - 0
lib/service/game/plug_orientation.dart → lib/service/game/plug_orientation.dart.bk


+ 0 - 0
lib/service/game/plug_sport_wear.dart → lib/service/game/plug_sport_wear.dart.bk


+ 0 - 0
lib/service/game/rule.dart → lib/service/game/rule.dart.bk


+ 0 - 0
lib/service/game/rule_in_order.dart → lib/service/game/rule_in_order.dart.bk


+ 0 - 0
lib/service/game/rule_in_order_allow_skip_cp.dart → lib/service/game/rule_in_order_allow_skip_cp.dart.bk


+ 0 - 0
lib/service/image.dart → lib/service/image.dart.bk


+ 62 - 0
lib/service/map/compass_updater.dart

@@ -0,0 +1,62 @@
+import 'dart:math';
+import 'package:simple_kalman/simple_kalman.dart';
+
+
+
+class CompassUpdater {
+  double? _lastAngle;
+  var _angle = 0.0;
+  final _kalman = SimpleKalman(errorMeasure: 256, errorEstimate: 150, q: 0.9);
+
+  double angleDis(double lastAngle, double nowAngle){
+
+
+    var tmp = lastAngle;
+    var lastDis = nowAngle - tmp;
+    while(true){
+      tmp += 360;
+      var dis = nowAngle - tmp;
+      if(lastDis.abs() < dis.abs()){
+        break;
+      }
+      lastDis = dis;
+      lastAngle=tmp;
+    }
+    tmp = lastAngle;
+    lastDis = nowAngle - tmp;
+    while(true){
+      tmp -= 360;
+      var dis = nowAngle - tmp;
+      if(lastDis.abs() < dis.abs()){
+        break;
+      }
+      lastDis = dis;
+      lastAngle=tmp;
+    }
+
+    return nowAngle - lastAngle;
+  }
+
+
+
+  double? updateRadians(double direction){
+    var nowAngle = direction * 180 / pi;
+    var lastAngle = _lastAngle;
+    if (lastAngle != null) {
+      _lastAngle = nowAngle;
+
+      var da = angleDis(lastAngle, nowAngle);
+
+      _angle += da;
+      return _kalman.filtered(_angle) * pi / 180.0;
+    } else {
+      _angle = nowAngle;
+      _lastAngle = nowAngle;
+      for(var i =0; i< 50; i++){
+        _kalman.filtered(_angle);
+      }
+      return null;
+    }
+  }
+
+}

+ 289 - 0
lib/service/map/game_model.dart

@@ -0,0 +1,289 @@
+import 'dart:math';
+import 'package:assets_audio_player/assets_audio_player.dart';
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:trackoffical_app/generated/assets.dart';
+import 'package:trackoffical_app/global.dart';
+import 'package:trackoffical_app/service/app.dart';
+import 'package:trackoffical_app/utils.dart';
+import '../../model/game_state.dart';
+import '../../model/m_control_point.dart';
+import '../../model/m_position.dart';
+import 'package:sensor/sensor.dart' as sensor;
+import '../../model/map_mode.dart';
+import '../../widget/matrix_gesture_detector.dart';
+import 'package:trackoffical_app/appcore/ffi.dart' as ffi;
+
+class GameModel{
+
+  DateTime? get startAt {
+    // final save = gameSrcState.value.pbGameSave;
+    // return save.hasStartAt()? save.startAt.toModel(): null;
+  }
+  DateTime? get endAt {
+    // final save = gameSrcState.value.pbGameSave;
+    // if(save.hasStopAt()){
+    //   if(save.stopAt.seconds==0){
+    //     return null;
+    //   }
+    //   return save.stopAt.toModel();
+    // }
+
+    return null;
+  }
+
+  final mapTransformMatrix = Matrix4.identity().obs;
+  bool get isStarted => startAt != null;
+  bool get isFinish => endAt != null;
+  final compassDiameter = 160.0.obs;
+  final myPositionHistory = <MPosition>[].obs;
+  final myPositionHistoryTmp = <MPosition>[];
+  final speedMPreS = 0.0.obs;
+  final isWalking = false.obs;
+  Rx<MPosition?> get myPosition => App.to.position;
+  final Rx<Offset?> myPositionOnMap = Rx(null);
+  final heartRate = 0.obs;
+  final heartRatePercent = 0.0.obs;
+  final ei = 0.0.obs;
+  final ck = 0.0.obs;
+  final kCal = 0.0.obs;
+  final exerciseKcal = 0.0.obs;
+  final hrMean = 0.obs;
+  final hrMax = 0.obs;
+  final stepCount = 0.obs;
+  /// 指北针弧度,移动时通过GPS判断
+  final compassRadiansFused = 0.0.obs;
+  final compassRadiansSrc = 0.0.obs;
+  final orientation = sensor.Orientation().obs;
+
+  final mapMode = MapMode.compass.obs;
+  Offset? mapRotateCenter;
+  var isAlwaysShowMyLocation = true;
+  var isEnableMyLocation = true;
+  /// 用户设置是否锁定旋转中心
+  final isLockScreenCenterToMyPosition = false.obs;
+  bool get isLockScreenCenterToMyPositionSystem =>
+      isLockScreenCenterToMyPosition.value
+          && isEnableUserLocation;
+
+  var accelerometerEvent = sensor.Orientation();
+  var isMoving = false;
+  final Rx<ffi.ZoneType?> zone = Rx(null);
+  final _isEnableUserLocation = App.to.userProfile.isEnableUserLocation.val.obs;
+  bool get isEnableUserLocation => _isEnableUserLocation.value;
+  set isEnableUserLocation(v){
+    _isEnableUserLocation.value = v;
+    App.to.userProfile.isEnableUserLocation.val =v;
+  }
+
+  /// 虚拟点打点有效半径冗余
+  static const controlPointEffectiveAreaRadiusKmOffset=0.002;
+  /// 虚拟点打点有效半径
+  double get controlPointEffectiveAreaRadiusKm => 100;
+      // GlobalVar.isGpsTest? 100:
+      // gameSrcState.value.pbGameData.vcpRadius.toDouble()/1000
+      //     + controlPointEffectiveAreaRadiusKmOffset;
+
+  /// 是否允许在开始点前预览所有点
+  bool get isAllowPreviewControlPoint => true; //gameSrcState.value.pbGameData.isPreview;
+  /// 是否允许显示地图
+  bool get isShowMap => true; //gameSrcState.value.pbGameData.isShowMap;
+  /// 是否允许跳点
+  bool get isAllowedPassCP => false; //gameSrcState.value.pbGameData.maxPassPoint > 0;
+  final trajectoryPoints = <Offset>[].obs;
+  /// 用户选项是否显示轨迹
+  final isShowTrajectory = true.obs;
+  bool get isDrawTrajectory => isShowTrajectory.value && isEnableUserLocation;
+
+  final controlPointWantSequence = <MControlPoint>[].obs;
+  final myPositionHistoryLen = 0.meter.obs;
+
+  final gameSrcState = GameState().obs;
+  bool get isUseRealNorth => App.to.userProfile.isCompassUseRealNorth.val;
+  set isUseRealNorth(v){ App.to.userProfile.isCompassUseRealNorth.val = v; }
+  var compassRealNorthOffset = 0.0;
+  var deviceSpeed = 0.0;
+  // Duration get gameQuestionShowDuration => gameSrcState.value.pbGameData.oiShowTime.seconds;
+
+  Distance get myPositionHistoryLenFromLastCP{
+    if(checkedPointsHistory.isEmpty){
+      return myPositionHistoryLen.value;
+    }
+    final cp = checkedPointsHistory.last;
+    return myPositionHistoryLen.value - cp.checkDistanceAfterStart;
+  }
+
+
+  Duration get startedDuration{
+    final b = startAt;
+    if(b!= null){
+      return App.to.now.difference(b);
+    }
+    return 0.seconds;
+  }
+
+  final paceSecondKm = 0.seconds.obs;
+  final paceSecondKmFromLastCP = 0.seconds.obs;
+
+  final checkedPointsHistory = <MControlPoint>[].obs;
+
+  int get checkedCount {
+    var i = 0;
+    // for (var one in gameSrcState.value.pbGameSave.checkedSortedList) {
+    //   if (one.isCheckSuccess) {
+    //     i++;
+    //   }
+    // }
+    return i;
+  }
+  final Rx<int?> nextPlanPointIndex=Rx(null);
+
+  int get validCPCount{
+    var cpChecked = checkedCount;
+    if(cpChecked < 0){
+      cpChecked = 0;
+    }
+    return cpChecked;
+  }
+
+  // 所有计分点数量
+  int get validCPAllNum{
+    return controlPointWantSequence.length;
+  }
+  // 打卡进度
+  double get checkProgress {
+    if (controlPointWantSequence.isEmpty) {
+      return 0;
+    }
+    return (checkedCount).toDouble() / (controlPointWantSequence.length);
+  }
+  MControlPoint? getNextWantPoint(int offset){
+    final i = checkedCount + offset;
+    return controlPointWantSequence.length > i?
+    controlPointWantSequence[i] : null;
+  }
+  MControlPoint? get nextPlanPoint{
+    final i = nextPlanPointIndex.value;
+    if(i==null){
+      return getNextWantPoint(0);
+    }
+
+    return controlPointWantSequence.length > i?
+    controlPointWantSequence[i] : null;
+  }
+  set nextPlanPoint(MControlPoint? v){
+    if(v==null){
+      nextPlanPointIndex.value=null;
+      return;
+    }
+
+    for(var i=0;i<controlPointWantSequence.length;i++ ){
+      if(v.intId==controlPointWantSequence[i].intId){
+        if(i < checkedCount){
+          return;
+        }
+
+        nextPlanPointIndex.value=i;
+
+        AssetsAudioPlayer.newPlayer().open(
+          Audio(Assets.soundCpJump),
+          autoStart: true,
+          showNotification: false
+        );
+
+
+        return;
+      }
+    }
+  }
+
+  bool get isInWantControlPointArea {
+    final p = getNextWantPoint(0);
+    if(p != null){
+      final disKm = nextWantCPDistanceKm;
+      if(disKm != null && p.type == MControlPointType.gps){
+        return disKm <= controlPointEffectiveAreaRadiusKm.km;
+      }
+    }
+    return false;
+  }
+  bool get isInPlanControlPointArea {
+    final p = nextPlanPoint;
+    if(p != null){
+      final disKm = nextPlanCPDistanceKm;
+      if(disKm != null && p.type == MControlPointType.gps){
+        return disKm <= controlPointEffectiveAreaRadiusKm.km;
+      }
+    }
+    return false;
+  }
+
+
+
+  Distance? get nextWantCPDistanceKm{
+
+    final p1 = myPosition.value;
+    final p2 = getNextWantPoint(0)?.position;
+    if(p1 != null && p2 != null){
+      return  p2.distance(p1);
+    }
+    return null;
+  }
+  Distance? get nextPlanCPDistanceKm{
+
+    final p1 = myPosition.value;
+    final p2 = nextPlanPoint?.position;
+    if(p1 != null && p2 != null){
+      return  p2.distance(p1);
+    }
+    return null;
+  }
+
+
+
+  double get compassPlantRadian {
+    if(mapMode.value == MapMode.compass){
+      return compassRadiansFused.value;
+    }
+
+    final ogRm = mapTransformMatrix.value.clone();
+    double radian = MatrixGestureDetector.decomposeToValues(ogRm).rotation;
+    return radian;
+  }
+  int get compassShowDegrees{
+    var d1 = -( compassPlantRadian - compassRadiansFused.value);
+    if(mapMode.value == MapMode.compass){
+      d1 = -compassPlantRadian;
+    }
+    var d = d1 *180~/pi;
+    while(d < 0){
+      d+=360;
+    }
+    while(d > 360){
+      d-=360;
+    }
+    return d;
+  }
+
+  void setRotateCenterToScreenCenter(){
+    final screenCenter =
+    Offset(App.to.screenSize.width / 2, App.to.screenSize.height / 2);
+    mapRotateCenter = screenCenter;
+  }
+
+  void clear(){
+    gameSrcState.value = GameState();
+    myPositionHistory.clear();
+    myPositionHistoryTmp.clear();
+    checkedPointsHistory.clear();
+    controlPointWantSequence.clear();
+    myPositionOnMap.value = null;
+    heartRate.value = 0;
+    heartRatePercent.value = 0;
+    ei.value = 0;
+    ck.value = 0;
+    myPositionHistoryLen.value = 0.meter;
+    nextPlanPointIndex.value=null;
+  }
+
+}

+ 838 - 0
lib/service/map/map.dart

@@ -0,0 +1,838 @@
+import 'dart:async';
+import 'dart:math';
+import 'package:flutter/cupertino.dart';
+import 'package:get/get.dart';
+import 'package:fixnum/fixnum.dart';
+import 'package:grpc/grpc.dart';
+import 'package:mobile_app/model/game_map.dart';
+import 'package:mobile_app/model/settlement.dart';
+import 'package:mobile_app/pb.dart' as pb;
+import 'package:mobile_app/service/app_map.dart';
+import 'package:mobile_app/service/game/game_model.dart';
+import 'package:mobile_app/service/game/plug.dart';
+import 'package:mobile_app/service/game/plug_location.dart';
+import 'package:mobile_app/service/game/plug_sport_wear.dart';
+import 'package:mobile_app/service/game/rule_in_order.dart';
+import 'package:mobile_app/service/game/show_position_controller.dart';
+import 'package:mobile_app/utils.dart';
+import 'package:mobile_app/view/ingame/settlement_view.dart';
+import 'package:vibration/vibration.dart';
+import 'package:wakelock/wakelock.dart';
+import '../../logger.dart';
+import '../api.dart';
+import '../../model.dart';
+import '../app.dart';
+import '../database.dart';
+import 'map_status.dart';
+import 'plug_orientation.dart';
+import 'rule.dart';
+import '../image.dart';
+
+enum GameStatus {
+  idle,
+  // 准备进入游戏
+  preparing,
+  loading,
+  playing,
+  settlement,
+}
+
+class GameService extends GetxService {
+  static GameService get to => Get.find();
+  final DatabaseService _database = Get.find();
+  final GameModel _model = Get.find();
+  final App _app = Get.find();
+  final errorMsg = ''.obs;
+  final name = "".obs;
+  var activityId = 0;
+  var mapRouteId = Int64(0);
+  var _status = GameStatus.idle;
+  Rule rule = RuleMock();
+  GameStatus get status => _status;
+
+  set status(GameStatus v) {
+    info('游戏状态:[$v]');
+    _status = v;
+  }
+
+  pb.GameSettlement _lastGameSettlement = pb.GameDetailReply();
+
+  pb.GameSettlement get lastGameSettlement => _lastGameSettlement;
+
+  MPosition? get myPosition => _model.myPosition.value;
+
+  Offset? get positionOnMap => _model.myPositionOnMap.value;
+
+  double get myPositionHistoryLenKm => _model.myPositionHistoryLen.value.km;
+
+  final _plugs = <Plug>[];
+
+  GameState get gameState => _model.gameSrcState.value;
+  var isShowCompass = true.obs;
+  static const _progressMap = 0.6;
+  static const _progressApi = 0.2;
+  static const _progressFinal = 0.2;
+  final _loadProgress = 0.0.obs;
+
+  double get loadProgress => _loadProgress.value;
+
+  List<MControlPoint> get controlPointWantSequence =>
+      _model.controlPointWantSequence;
+
+  bool get isNfcScanUseDialog {
+    final platform = _app.platformInfo;
+    if (platform is PlatformInfoIOS) {
+      if (platform.deviceVersion >= 8) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  // 创建时间
+  DateTime get createTime => gameState.createTime;
+
+  // 关门时间
+  Duration get maxPassDuration => gameState.pbGameData.maxDuration.toDuration();
+
+  // 强制结束时间
+  Duration get maxForcedEndDuration =>
+      gameState.pbGameData.maxForcedEndDuration.toDuration();
+
+  DateTime get now => _app.now;
+
+  // 打开始点的时间
+  DateTime? get startAt => _model.startAt;
+
+  DateTime? get endAt => _model.endAt;
+
+  List<pb.ControlPoint> get _controlPointWantSequence =>
+      gameState.pbGameData.controlPointSortedList;
+
+  List<pb.ControlPointSimple> get _controlPointAll =>
+      gameState.pbGameData.controlPointAll;
+
+  var _lastCheckedPoint = Int64(0);
+  var _lastCheckedPointTime = DateTime(0);
+
+  List<MControlPoint> get checkedPointsHistory => _model.checkedPointsHistory;
+  final beginDuration = 0.seconds.obs;
+  final mapStatus = MapStatus();
+  Timer? _beginDurationTicker;
+  Timer? _checkStopTicker;
+
+  int get checkedCount => _model.checkedCount;
+
+  // 所有计分点数量
+  int get controlPointAllNum => _model.validCPAllNum;
+
+  // 打卡进度
+  double get checkProgress => _model.checkProgress;
+
+  bool get isOutBoundary {
+    final p = _model.myPositionOnMap.value;
+
+    if (p != null) {
+      final mapWidth = mapStatus.gameMapData.width;
+      final mapHeight = mapStatus.gameMapData.height;
+
+      if (p.dx <= 0 || p.dx >= mapWidth || p.dy <= 0 || p.dy >= mapHeight) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  AnimationController? showLocationController;
+
+  showLocation() {
+    final p = positionOnMap;
+    if (p != null) {
+      final dst = _model.mapRotateCenter;
+
+      if (_model.isEnableUserLocation && !_model.isAlwaysShowMyLocation) {
+        Get.find<ShowPositionController>().show();
+      }
+
+      if (dst != null) {
+        mapStatus.movePicPointTo(p, dst);
+      }
+    }
+  }
+
+  _setStartAt(DateTime? time) {
+    if (time != null) {
+      gameState.pbGameSave.startAt = time.toPb();
+    } else {
+      gameState.pbGameSave.clearStartAt();
+    }
+    _model.gameSrcState.refresh();
+  }
+
+  _setEndAt(DateTime? time) {
+    if (time != null) {
+      gameState.pbGameSave.stopAt = time.toPb();
+    } else {
+      gameState.pbGameSave.clearStopAt();
+    }
+    _model.gameSrcState.refresh();
+  }
+
+  _recordLastPoint(Int64 id) {
+    _lastCheckedPoint = id;
+    _lastCheckedPointTime = now;
+  }
+
+  bool _isCheckTooFast(Int64 id) {
+    return _lastCheckedPoint == id &&
+        now.difference(_lastCheckedPointTime) <= 10.seconds;
+  }
+
+  bool isPointStart(pb.GameSaveControlPoint p) {
+    final seq = _controlPointWantSequence;
+    if (seq.isNotEmpty) {
+      return p.controlPointId == seq.first.id;
+    }
+    return false;
+  }
+
+  bool isPointFinish(pb.GameSaveControlPoint p) {
+    final seq = _controlPointWantSequence;
+    if (seq.isNotEmpty) {
+      return p.controlPointId == seq.last.id;
+    }
+    return false;
+  }
+
+  void setBeginMatrix() {
+    if (mapStatus.isSetBeginMatrix) {
+      return;
+    }
+
+    final next = _model.nextPlanPoint;
+    final f = _model.mapRotateCenter;
+    if (next != null && f != null) {
+      mapStatus.movePicPointTo(next.onMap, f);
+      mapStatus.isSetBeginMatrix = true;
+    }
+  }
+
+  pb.ControlPointSimple gameSaveControlPointFindInProject(
+      pb.GameSaveControlPoint p) {
+    final all = gameState.pbGameData.controlPointAll;
+    for (final one in all) {
+      if (one.id == p.controlPointId) {
+        return one;
+      }
+    }
+    return pb.ControlPointSimple();
+  }
+
+  Future<List<MControlPoint>> _getControlPointWantSequence() async {
+    final out = <MControlPoint>[];
+    final checkedIndex = checkedCount;
+
+    for (var i = 0; i < _controlPointWantSequence.length; i++) {
+      final value = _controlPointWantSequence[i];
+      final one = value.toModel();
+      one.sn = '$i';
+      if (i == 0) {
+        one.isStart = true;
+      }
+      if (i == _controlPointWantSequence.length - 1) {
+        one.isFinish = true;
+      }
+
+      one.isSuccess = i < checkedIndex;
+      one.isNext = i == checkedIndex;
+      one.onMap =
+          await mapStatus.gameMapData.worldToPixel(value.mapPosition.toModel());
+
+      final extraInfo = one.extraInfo;
+      if(extraInfo is CPExtraInfoChoiceQuestion){
+        extraInfo.beanCount = gameState.pbGameData.answerSysPoint;
+        await extraInfo.image?.loadMemory();
+      }
+
+
+      out.add(one);
+    }
+
+    return out;
+  }
+
+  MControlPoint? getNextWantPoint(int offset) =>
+      _model.getNextWantPoint(offset);
+
+  MControlPoint? getLastCheckedPoint() {
+    if (checkedPointsHistory.isNotEmpty) {
+      return checkedPointsHistory.last;
+    } else {
+      return null;
+    }
+  }
+
+  void _checkGameStop({bool willToSettlementView = false}) {
+    if ([
+      GameStatus.preparing,
+      GameStatus.playing,
+    ].contains(status)) {
+      if (now.difference(createTime) > maxForcedEndDuration) {
+        gameGiveUp(willToSettlementView: willToSettlementView);
+      }
+    }
+  }
+
+  Future<void> _saveToDatabase() async {
+    await DatabaseService.to.saveGameState(gameState);
+  }
+
+  Future<void> _saveToServer() async {
+    while (!isClosed) {
+      try {
+        final save = gameState.pbGameSave;
+        await ApiService.to
+            .gameSaveUpload(pb.GameSaveUploadRequest()..gameSave= save);
+
+        return;
+      } on GrpcError catch (e) {
+        warn('上传失败:', e);
+        if (e.code != StatusCode.unavailable) {
+          return;
+        }
+      } catch (e) {
+        warn('上传失败:', e);
+        return;
+      }
+
+      await Future.delayed(500.milliseconds);
+    }
+  }
+
+  void _checkHistoryAdd(MControlPoint cp) {
+    checkedPointsHistory.add(cp);
+    gameState.pbGameSave.checkedSortedList.add(cp.toPbSave());
+  }
+
+  void _updateCheckHistory(){
+    gameState.pbGameSave.checkedSortedList.clear();
+    gameState.pbGameSave.checkedSortedList.addAll(checkedPointsHistory.map((e) => e.toPbSave()).toList());
+  }
+
+  void save() {
+    _updateCheckHistory();
+    _saveToDatabase().then((value) => info('本地存档完成'));
+    _saveToServer().then((value) => info('上传存档完成'));
+  }
+
+  Future<void> gameGiveUp({bool willToSettlementView = false}) async {
+    // if(status == GameStatus.idle || status == GameStatus.settlement){
+    //   return;
+    // }
+    _gameStopSetValues();
+    _updateCheckHistory();
+    _saveToDatabase().then((value) => info('本地存档完成'));
+    _settlement(isGiveUp: true, willToSettlementView: willToSettlementView);
+  }
+
+  void _gameStopSetValues({DateTime? now}) {
+    info('游戏结束');
+    if (now != null) {
+      _setEndAt(now);
+    } else {
+      _setEndAt(this.now);
+    }
+  }
+
+  void _updateNewCPState(MControlPoint point, {DateTime? now}) {
+    now = now ?? this.now;
+    point.checkAfterStart = now.difference(startAt ?? now);
+    point.checkAfterPrev = point.checkAfterStart;
+    point.checkDistanceAfterStart = _model.myPositionHistoryLen.value;
+    point.checkDistanceAfterPrev = point.checkDistanceAfterStart;
+    final last = getLastCheckedPoint();
+    if (last != null) {
+      point.checkAfterPrev = point.checkAfterStart - last.checkAfterStart;
+      point.checkDistanceAfterPrev = point.checkDistanceAfterStart - last.checkDistanceAfterStart;
+    }
+  }
+
+  checkPointNFC(
+    String identifier,
+      void Function(MControlPoint cp) onChecked,
+      Future<bool> Function () onConfirmFinish,
+    void Function(pb.ControlPointSimple point) onProjectPoint,
+    VoidCallback onNoPoint,
+  ) {
+    final checkedPoint = _findControlPointInRouteByNfcId(identifier);
+    if (checkedPoint != null) {
+      checkPoint(checkedPoint, onChecked, onConfirmFinish);
+    } else {
+      final point = _findControlPointInProjectByNfcId(identifier);
+      if (point != null) {
+        if (_isCheckTooFast(point.id)) {
+          return;
+        }
+        final result = point.toModel();
+        _updateNewCPState(result);
+        result.isSuccess = false;
+        _checkHistoryAdd(result);
+        save();
+        _recordLastPoint(point.id);
+        onProjectPoint(point);
+      } else {
+        onNoPoint();
+      }
+    }
+  }
+
+  checkPointGps(
+    void Function(MControlPoint cp) onChecked,
+      Future<bool> Function () onConfirmFinish,
+  ) {
+
+    if(_model.isInPlanControlPointArea){
+      pb.ControlPoint? checkedPoint;
+      final point = _model.nextPlanPoint;
+      if (point != null) {
+        checkedPoint = _findControlPointInRouteByM(point);
+      }
+      checkPoint(checkedPoint!, onChecked, onConfirmFinish);
+    }else if (_model.isInWantControlPointArea) {
+      pb.ControlPoint? checkedPoint;
+      final point = _model.getNextWantPoint(0);
+      if (point != null) {
+        checkedPoint = _findControlPointInRouteByM(point);
+      }
+      checkPoint(checkedPoint!, onChecked, onConfirmFinish);
+    }
+  }
+
+
+
+
+
+  Future<void> checkPoint(
+    pb.ControlPoint checkedPoint,
+    void Function (MControlPoint cp) onChecked,
+      /// 打了结束点,询问是否结束
+      Future<bool> Function () onConfirmFinish,
+  ) async{
+    final cp = checkedPoint.toModel();
+
+    if (rule.checkNeedReturn(cp)){
+      return;
+    }
+
+    final now = this.now;
+
+    final result = rule.checkPoint(checkedPoint.toModel());
+
+
+    var isFinish = result.isSuccess && result.isFinish;
+
+    if(!result.isSuccess && result.isFinish){
+      isFinish = await onConfirmFinish();
+      if(!isFinish){
+        return;
+      }
+    }
+
+    _updateNewCPState(result, now: now);
+
+    if(result.isStart && result.isSuccess){
+      _setStartAt(now);
+    }
+
+    if(isFinish){
+      _gameStopSetValues(now: now);
+    }
+
+    _checkHistoryAdd(result);
+
+    if(startAt!=null){
+      gameState.pbGameSave.duration = now.difference(startAt!).toPb();
+
+      if(endAt != null){
+        gameState.pbGameSave.duration = endAt!.difference(startAt!).toPb();
+      }
+    }
+
+    _model.gameSrcState.refresh();
+
+    if(isFinish){
+      _settlement();
+    }else{
+      save();
+    }
+    rule.recordLastPoint(cp);
+    onChecked(result);
+  }
+
+  void showNextPoint() {
+    final next = _model.nextPlanPoint;
+    final focalPoint = _model.mapRotateCenter;
+    if (next != null && focalPoint != null) {
+      mapStatus.movePicPointTo(next.onMap, focalPoint);
+    }
+  }
+
+  Future<void> gameGiveUpAndToFinishView({GameState? state}) async {
+    if (state != null) {
+      _model.gameSrcState.value = state;
+    }
+
+    gameGiveUp();
+    SettlementView.show();
+    // Get.offAll(() => const GameFinishView(),
+    //     binding: GameFinishView.bindings());
+  }
+
+  Future<void> _gameReset() async {
+    errorMsg.value = '';
+    _model.clear();
+    await _plugsClear();
+  }
+
+  Future<void> gameStart() async {
+    info('项目Id[$activityId]准备开始');
+    await _gameReset();
+
+    final data = await ApiService.to.gameStart(activityId, mapRouteId);
+    _model.gameSrcState.value = data.toGameState();
+    status = GameStatus.preparing;
+    _saveToDatabase();
+    info('活动Id[$activityId],游戏Id[${gameState.pbGameData.gameId}]已开始');
+  }
+
+  Future<void> gameLoad() async {
+    info('载入项目[$activityId], Id[${gameState.pbGameData.gameId}]');
+    await _plugsClear();
+
+    _loadProgress.value = 0;
+    status = GameStatus.loading;
+    _app.userProfile.cleanGameSettingsLock();
+    _app.userProfile.gameSettingsLoadLock(gameState.pbGameData.ruleList);
+
+    /// 游戏规则
+    // rule = RuleInOrder();
+    _model.compassRealNorthOffset = gameState.pbGameData.declination * pi / 180;
+
+    _loadProgress.value = _progressApi;
+
+    final gameMap = gameState.pbGameData.mapZip.toGameMap();
+    mapStatus.gameMapData = gameMap;
+
+    await gameMap.loadMemory(onReceiveProgress: (c, a) {
+      if (a > 0) {
+        var p = c.toDouble() / a;
+        p = p * _progressMap + _progressApi;
+        _loadProgress.value = p;
+      }
+    });
+
+    mapStatus.mapImageData.value = gameMap.pic!;
+
+    // --- 确定地图图片首次缩放比例 ---
+    final screenSize = _app.screenSize;
+    final fitted = applyBoxFit(
+        BoxFit.contain,
+        Size(gameMap.width, gameMap.height),
+        Size(screenSize.width, screenSize.height));
+
+    mapStatus.picFirstScale = fitted.destination.width / fitted.source.width;
+    // --------------
+    _model.mapRotateCenter =
+        Offset(screenSize.width / 2, screenSize.height / 2);
+    await mapStatus.resetMatrix();
+
+    _model.controlPointWantSequence.value =
+        await _getControlPointWantSequence();
+    _gameLoadCheckedCP();
+
+    final plugLocation = PlugLocation(
+        gameMap: gameMap,
+        lastInfo: _model.gameSrcState.value.pbGameSave.gameGpsInfos);
+
+    _plugs.add(plugLocation);
+    _plugs.add(PlugSportWear(
+        lastHr: _model.gameSrcState.value.pbGameSave.gameHrInfos));
+    _plugs.add(PlugOrientation(mapStatus: mapStatus));
+
+    await _plugsAllInit();
+    _loadProgress.value = 1;
+    status = GameStatus.playing;
+    Wakelock.enable();
+    info('载入完成');
+  }
+
+  void _gameLoadCheckedCP() {
+    final controlPointWantIdValueMap = <Int64, MControlPoint>{};
+    final controlPointAllIdValueMap = <Int64, pb.ControlPointSimple>{};
+
+    for (var one in _model.controlPointWantSequence) {
+      controlPointWantIdValueMap[one.intId] = one;
+    }
+    for (var one in gameState.pbGameData.controlPointAll) {
+      controlPointAllIdValueMap[one.id] = one;
+    }
+    for (var i = 0; i < gameState.pbGameSave.checkedSortedList.length; i++) {
+      final one = gameState.pbGameSave.checkedSortedList[i];
+      final his = one.toModel();
+      final hisInfo1 = controlPointWantIdValueMap[his.intId];
+      final hisInfo2 = controlPointAllIdValueMap[his.intId];
+      if (hisInfo2 != null) {
+        his.updateBySimple(hisInfo2);
+      }
+      if (hisInfo1 != null) {
+        his.updateBy(hisInfo1);
+        his.type = hisInfo1.type;
+      }
+      checkedPointsHistory.add(his);
+    }
+
+    for (var i = 0; i < checkedPointsHistory.length; i++) {
+      final his = checkedPointsHistory[i];
+      if (i > 0) {
+        final last = checkedPointsHistory[i - 1];
+        his.checkAfterPrev = his.checkAfterStart - last.checkAfterStart;
+        his.checkDistanceAfterPrev = his.checkDistanceAfterStart - last.checkDistanceAfterStart;
+      } else {
+        his.checkAfterPrev = his.checkAfterStart;
+        his.checkDistanceAfterPrev = his.checkDistanceAfterStart;
+      }
+    }
+  }
+
+  Future<void> _plugsAllInit() async {
+    for (var one in _plugs) {
+      await one.init();
+    }
+  }
+
+  Future<void> _plugsClear() async {
+    for (var one in _plugs) {
+      one.close();
+    }
+    for (var one in _plugs) {
+      await one.join();
+    }
+    _plugs.clear();
+  }
+
+  Settlement getSettlement() {
+    return Settlement(
+        data: gameState.pbGameData,
+        save: gameState.pbGameSave,
+        durationAfterStartCheck: beginDuration.value);
+  }
+
+  pb.ControlPoint? _findControlPointInRouteByNfcId(String identifier) {
+    pb.ControlPoint? found;
+    for (var one in _controlPointWantSequence) {
+      for (var nfcId in one.nfcIdList) {
+        if (nfcId.toUpperCase() == identifier.toUpperCase()) {
+          found = one;
+          break;
+        }
+      }
+    }
+    return found;
+  }
+
+  pb.ControlPoint? _findControlPointInRouteByM(MControlPoint point) {
+    pb.ControlPoint? found;
+    for (var one in _controlPointWantSequence) {
+      if (one.id == point.intId) {
+        found = one;
+        break;
+      }
+    }
+    return found;
+  }
+
+  pb.ControlPointSimple? _findControlPointInProjectByNfcId(String identifier) {
+    for (var one in _controlPointAll) {
+      for (var nfcId in one.nfcIdList) {
+        if (nfcId.toUpperCase() == identifier.toUpperCase()) {
+          return one;
+        }
+      }
+    }
+    return null;
+  }
+
+  Future<void> _settlementDeal(bool isGiveUp) async {
+    while (!isClosed) {
+      try {
+        final save = gameState.pbGameSave;
+        await ApiService.to
+            .gameSaveUpload(pb.GameSaveUploadRequest()..gameSave= save);
+        info('进度已上传');
+        break;
+      } on GrpcError catch (e) {
+        if (e.code == StatusCode.unavailable) {
+          errorMsg.value = '无法连接至服务器,正在重试';
+        } else {
+          break;
+        }
+        error(e);
+      } catch (e) {
+        error(e);
+        break;
+      }
+    }
+
+    await _plugsClear();
+
+    while (!isClosed) {
+      try {
+        info('正在结算');
+        _lastGameSettlement = await ApiService.to
+            .gameFinish(gameState.pbGameData.gameId, isGiveUp);
+        info('结算完成');
+        break;
+      } on GrpcError catch (e) {
+        if (e.code == StatusCode.unavailable) {
+          errorMsg.value = '网络错误,正在重试';
+        } else {
+          break;
+        }
+        error(e);
+        Future.delayed(500.milliseconds);
+      } catch (e) {
+        error(e);
+        break;
+      }
+    }
+
+    await _saveToDatabase();
+    status = GameStatus.idle;
+  }
+
+  _settlement({bool isGiveUp = false, bool willToSettlementView = false}) {
+    _updateCheckHistory();
+    status = GameStatus.settlement;
+    errorMsg.value = '';
+    _settlementDeal(isGiveUp).then((value) => info('结算完成'));
+    if (willToSettlementView) {
+      SettlementView.show();
+    }
+  }
+
+  @override
+  void onReady() {
+    _beginDurationTicker = Timer.periodic(100.milliseconds, (timer) {
+      final startAt = this.startAt;
+      if (startAt != null) {
+        final end = endAt ?? now;
+        beginDuration.value = end.difference(startAt);
+      } else {
+        beginDuration.value = 0.seconds;
+      }
+    });
+  }
+
+  @override
+  void onClose() {
+    _checkStopTicker?.cancel();
+    _beginDurationTicker?.cancel();
+  }
+
+  Future<bool> loadOnlineUnFinishGame() async {
+    try {
+      final online = await ApiService.to.getInGameData();
+      info('存在线上未完成游戏');
+      status = GameStatus.preparing;
+      _model.gameSrcState.value = GameState()
+        ..pbGameData = online.data
+        ..pbGameSave = online.save;
+      _checkGameStop();
+      return true;
+    } on GrpcError catch (e) {
+      if (e.code != StatusCode.notFound) {
+        warn(e);
+      }
+      return false;
+    } catch (e) {
+      warn(e);
+      return false;
+    }
+  }
+
+  void workAutoSave() async {
+    while (!isClosed) {
+      await Future.delayed(500.milliseconds);
+
+      if (_model.gameSrcState.value.pbGameData.gameId > 0 &&
+          _model.isStarted &&
+          !_model.isFinish) {
+        await _saveToDatabase();
+      }
+    }
+  }
+
+  void workTrajectory() async {
+    while (!isClosed) {
+      await Future.delayed(1000.milliseconds);
+      final duration = _app.userProfile.inGameTrajectorySeconds.val.seconds;
+
+      var out = <Offset>[];
+      for (var i = _model.myPositionHistory.length - 1; i >= 0; i--) {
+        var one = _model.myPositionHistory[i];
+        if (now.difference(one.timestamp) > duration) {
+          break;
+        }
+
+        out.add(await mapStatus.gameMapData.worldToPixel(one));
+      }
+      _model.trajectoryPoints.clear();
+      _model.trajectoryPoints.addAll(out);
+    }
+  }
+
+  void workPace() async {
+    while (!isClosed) {
+      await Future.delayed(1000.milliseconds);
+      final startDuration = _model.startedDuration;
+      if (startDuration.inMilliseconds == 0) {
+        continue;
+      }
+
+      _model.paceSecondKm.value =
+          pacePerKm(myPositionHistoryLenKm.km, startDuration);
+      if (checkedPointsHistory.isEmpty) {
+        _model.paceSecondKmFromLastCP.value = _model.paceSecondKm.value;
+      } else {
+        final cp = checkedPointsHistory.last;
+        _model.paceSecondKmFromLastCP.value = pacePerKm(
+            _model.myPositionHistoryLenFromLastCP,
+            startDuration - cp.checkAfterStart);
+      }
+    }
+  }
+
+  static Future<GameService> init() async {
+    final gs = GameService();
+
+    gs.mapStatus.canVibrate = await Vibration.hasVibrator() ?? false;
+    final save = await gs._database.getExistGameData();
+    if (save != null) {
+      info('存在本地未完成游戏');
+      gs.status = GameStatus.preparing;
+      gs._model.gameSrcState.value = save.toState();
+      gs._checkGameStop();
+    } else {
+      gs.loadOnlineUnFinishGame();
+    }
+
+    gs._checkStopTicker = Timer.periodic(100.milliseconds, (timer) {
+      gs._checkGameStop(willToSettlementView: true);
+    });
+
+    gs.workAutoSave();
+    gs.workTrajectory();
+    gs.workPace();
+    return gs;
+  }
+}

+ 266 - 0
lib/service/map/map_status.dart

@@ -0,0 +1,266 @@
+import 'dart:async';
+import 'dart:math';
+import 'dart:typed_data';
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:mobile_app/logger.dart';
+import 'package:mobile_app/model/game_map.dart';
+import 'package:mobile_app/service/app.dart';
+import 'package:mobile_app/service/game/game_model.dart';
+import 'package:vibration/vibration.dart';
+import '../../model/map_mode.dart';
+import '../../widget/matrix_gesture_detector.dart';
+import 'package:vector_math/vector_math_64.dart' as vec;
+
+class MapStatus {
+
+  var canVibrate = false;
+  var mapImageData = Uint8List(0).obs;
+  var gameMapData = GameMap();
+  final GameModel _model = Get.find();
+  Rx<Matrix4> get matrix => _model.mapTransformMatrix;
+  Rx<MapMode> get mapMode => _model.mapMode;
+  double get compassAngle => _model.compassRadiansFused.value;
+  var lastCompassRadians = 0.0;
+  var vibrateAccumulation = 0.0;
+  var isTouching = false;
+  double picFirstScale = 1;
+  var isSetBeginMatrix = false;
+  final isShowMapScale = false.obs;
+  Timer? _showMapScaleTimer;
+  double _mapLenMeter=1;
+
+  // 比例尺  屏幕尺寸/米 实时
+  final mapScale = 0.0.obs;
+  // 比例尺  屏幕尺寸/米 原始
+  var mapScaleSrc = 0.0;
+
+
+  double get rotateRadian {
+    final ogRm = matrix.value.clone();
+    double radian = MatrixGestureDetector.decomposeToValues(ogRm).rotation;
+    return radian;
+  }
+  double get compassPlantRadian =>_model.compassPlantRadian;
+
+  final _translationUpdater = _ValueUpdater<Offset>(
+    onUpdate: (oldVal, newVal) => newVal - (oldVal ?? Offset.zero),
+  );
+  final _rotationUpdater = _ValueUpdater<double>(
+    onUpdate: (oldVal, newVal) => newVal - (oldVal ?? 0),
+  );
+  final _scaleUpdater = _ValueUpdater<double>(
+    onUpdate: (oldVal, newVal) => newVal / (oldVal ?? 1),
+  );
+
+  Future<void> resetMatrix() async{
+    matrix.value = Matrix4.identity();
+    lastCompassRadians = 0.0;
+    _rotationUpdater.value = 0;
+    _translationUpdater.value = Offset.zero;
+    _scaleUpdater.value = 1;
+
+
+    isSetBeginMatrix=false;
+
+    matrix.value = _doScale(4, matrix.value);
+
+    const p0Src = Offset(0, 0);
+    final p1Src = Offset(gameMapData.width, 0);
+    final mapTopLeftLocation = await gameMapData.pixelToWorld(p0Src);
+    final mapTopRightLocation = await gameMapData.pixelToWorld(p1Src);
+    final disKm = mapTopLeftLocation.distance(mapTopRightLocation);
+    _mapLenMeter = disKm.km;
+    final screenLen = App.to.screenSize.width;
+    mapScaleSrc = screenLen / _mapLenMeter;
+
+    calculateMapScale();
+
+  }
+
+
+  Offset picOffsetToScreen(Offset offset){
+    var thisOffset = Offset(offset.dx * picFirstScale, offset.dy * picFirstScale);
+    final mr= matrix.value.applyToVector3Array([thisOffset.dx, thisOffset.dy, 0]);
+    return Offset(mr[0], mr[1]);
+  }
+
+  void movePicPointTo(Offset src, Offset dst){
+    final pOnScreen = picOffsetToScreen(src);
+    final dis = dst - pOnScreen;
+    final tranM = Matrix4.translationValues(dis.dx, dis.dy, 0);
+    matrix.value = tranM * matrix.value;
+  }
+
+  Matrix4? _getRotationMatrix(
+      double radiansDelta,
+      Offset focalPoint,
+      {bool willVibrate=false}) {
+
+    if (_rotationUpdater.value == null || _rotationUpdater.value!.isNaN) {
+      _rotationUpdater.value = radiansDelta;
+    } else {
+      final rotationDelta = _rotationUpdater.update(radiansDelta);
+
+      var c = cos(rotationDelta);
+      var s = sin(rotationDelta);
+      var dx = (1 - c) * focalPoint.dx + s * focalPoint.dy;
+      var dy = (1 - c) * focalPoint.dy - s * focalPoint.dx;
+      final rotationDeltaMatrix = Matrix4(
+          c,  s,  0,  0,
+          -s, c,  0,  0,
+          0,  0,  1,  0,
+          dx, dy, 0,  1);
+
+      if(willVibrate){
+        vibrateAccumulation += vec.degrees(rotationDelta);
+        if (vibrateAccumulation.abs() >= 5) {
+          vibrateAccumulation = 0;
+          if (canVibrate) {
+            Vibration.vibrate(duration: 20, repeat: 1);
+          }
+        }
+      }
+
+      return rotationDeltaMatrix;
+    }
+    return null;
+  }
+
+
+
+
+  void setRotate(double radians) {
+    final focalPoint = _model.mapRotateCenter;
+    if(focalPoint != null){
+      final rotate =  _getRotationMatrix(radians, focalPoint);
+      if(rotate!= null){
+        var matrix = this.matrix.value;
+        this.matrix.value = rotate * matrix;
+      }
+    }
+  }
+
+
+  void mapModeSwitch() {
+
+    resetMatrix();
+    switch (mapMode.value) {
+      case MapMode.original:
+        mapMode.value = MapMode.compass;
+        break;
+      case MapMode.compass:
+        mapMode.value = MapMode.original;
+        break;
+    }
+  }
+
+  void onMapTouchScaleStart(ScaleStartDetails details) {
+    isTouching=true;
+    _translationUpdater.value = details.focalPoint;
+    _rotationUpdater.value = double.nan;
+    _scaleUpdater.value = 1.0;
+  }
+
+  Matrix4 _doScale(double scaleDelta, Matrix4 matrix){
+    final focalPoint = _model.mapRotateCenter!;
+    var dx = (1 - scaleDelta) * focalPoint.dx;
+    var dy = (1 - scaleDelta) * focalPoint.dy;
+    final scaleDeltaMatrix = Matrix4(
+        scaleDelta, 0, 0, 0,
+        0, scaleDelta, 0, 0,
+        0, 0, 1, 0,
+        dx, dy, 0, 1);
+    return scaleDeltaMatrix * matrix;
+  }
+
+  void onMapTouchScaleUpdate(ScaleUpdateDetails details, Size screen) {
+
+    final focalPoint = _model.mapRotateCenter!;
+
+    var matrix = this.matrix.value;
+
+    // 平移
+    if(!_model.isLockScreenCenterToMyPositionSystem){
+      final translationDelta = _translationUpdater.update(details.focalPoint);
+      final translationDeltaMatrix =
+      Matrix4.translationValues(translationDelta.dx, translationDelta.dy, 0);
+      matrix = translationDeltaMatrix * matrix;
+    }
+
+    // 缩放
+    final scale = matrix[0].abs();
+    if (details.scale != 1.0) {
+
+      final zoomOutLimit = scale > 0.5 || details.scale > 1;
+      // final zoomInLimit = scale < 8 || details.scale < 1;
+      final zoomInLimit =  mapScale < 1.7 || details.scale < 1;
+
+
+      if(zoomOutLimit && zoomInLimit){
+        final scaleDelta = _scaleUpdater.update(details.scale);
+        matrix = _doScale(scaleDelta, matrix);
+      }
+    }
+
+    // 旋转
+    var rotationDelta = 0.0;
+    var willVibrate = false;
+    switch (mapMode.value) {
+      case MapMode.original:
+        rotationDelta = details.rotation;
+        willVibrate = true;
+        break;
+      case MapMode.compass:
+        break;
+    }
+
+    if(rotationDelta != 0){
+      final rotationDeltaMatrix = _getRotationMatrix(
+          rotationDelta, focalPoint, willVibrate: willVibrate);
+
+      if(rotationDeltaMatrix!= null){
+        matrix = rotationDeltaMatrix * matrix;
+      }
+    }
+
+    this.matrix.value = matrix;
+    calculateMapScale();
+  }
+
+
+  calculateMapScale(){
+    const p0Src = Offset(0, 0);
+    final p1Src = Offset(gameMapData.width, 0);
+
+    final p0Dst = picOffsetToScreen(p0Src);
+    final p1Dst = picOffsetToScreen(p1Src);
+
+    final disPx = sqrt((p1Dst.dx - p0Dst.dx)* (p1Dst.dx - p0Dst.dx)
+        + (p1Dst.dy - p0Dst.dy) * (p1Dst.dy - p0Dst.dy));
+
+    final scale = disPx / _mapLenMeter;
+    mapScale.value = scale;
+    isShowMapScale.value = true;
+    _showMapScaleTimer?.cancel();
+    _showMapScaleTimer = Timer(3.seconds, () {
+      isShowMapScale.value = false;
+    });
+  }
+}
+
+typedef _OnUpdate<T> = T Function(T? oldValue, T newValue);
+
+class _ValueUpdater<T> {
+  final _OnUpdate<T> onUpdate;
+  T? value;
+
+  _ValueUpdater({required this.onUpdate});
+
+  T update(T newValue) {
+    T updated = onUpdate(value, newValue);
+    value = newValue;
+    return updated;
+  }
+}
+

+ 6 - 0
lib/service/map/plug.dart

@@ -0,0 +1,6 @@
+import 'dart:async';
+import 'package:trackoffical_app/model/closeable.dart';
+
+abstract class Plug extends Closeable{
+    Future<void> init();
+}

+ 150 - 0
lib/service/map/plug_orientation.dart

@@ -0,0 +1,150 @@
+import 'dart:async';
+import 'dart:math';
+import 'package:get/get.dart';
+import 'package:trackoffical_app/logger.dart';
+import 'package:trackoffical_app/model.dart';
+import 'package:trackoffical_app/service/app.dart';
+import 'package:trackoffical_app/service/map/compass_updater.dart';
+import 'package:trackoffical_app/service/map/map_status.dart';
+import 'package:sensors_plus/sensors_plus.dart';
+import 'package:vector_math/vector_math.dart';
+import 'game_model.dart';
+import 'plug.dart';
+import 'package:sensor/sensor.dart';
+import 'package:simple_kalman/simple_kalman.dart';
+
+
+class PlugOrientation extends Plug {
+  PlugOrientation({required this.mapStatus});
+
+  StreamSubscription<Orientation>? compassListener;
+  StreamSubscription<AccelerometerEvent>? accelerometer;
+
+  final GameModel _model = Get.find();
+  final MapStatus mapStatus;
+
+  final _angleFusedUpdater = CompassUpdater();
+  final _angleSrcUpdater = CompassUpdater();
+
+  var _lastAccelerometer = AccelerometerEvent(0, 0, 0);
+  var _lastAccelerometerTime = DateTime.now();
+
+  @override
+  Future<void> init() async {
+    _model.isMoving =false;
+    compassListener = Sensor.orientationStream.listen((event) {
+      _model.orientation.value = event;
+      var direction = event.z;
+      if (_model.isUseRealNorth) {
+        direction += _model.compassRealNorthOffset;
+      }
+
+      final src = _angleSrcUpdater.updateRadians(direction);
+      if(src!=null){
+        _model.compassRadiansSrc.value = -src;
+      }
+
+      // GPS 方向
+      final gpsD = gpsDirection();
+      _model.isMoving = gpsD != null;
+      if (gpsD != null) {
+        direction = gpsD;
+      }
+
+      final fused = _angleFusedUpdater.updateRadians(direction);
+      if(fused!=null){
+        _model.compassRadiansFused.value = -fused;
+      }
+
+    });
+
+
+    accelerometer = accelerometerEvents.listen((AccelerometerEvent event) {
+      final now = DateTime.now();
+      if(now.difference(_lastAccelerometerTime) >= 1.seconds){
+        var sum = (event.x - _lastAccelerometer.x).abs() +
+            (event.y - _lastAccelerometer.y).abs() +
+            (event.z - _lastAccelerometer.z).abs();
+
+
+
+        final d = now.difference(_lastAccelerometerTime);
+
+        _model.deviceSpeed = sum / (d.inMilliseconds.toDouble() / 1000);
+
+        _lastAccelerometerTime = now;
+        _lastAccelerometer = event;
+      }
+    });
+  }
+
+
+
+
+  /// GPS 方向
+  double? gpsDirection() {
+    if(_model.deviceSpeed < 1){
+      return null;
+    }
+
+    final locations = <MPosition>[];
+    var disKm = 0.0;
+    final t = 4.seconds;
+    final bt = App.to.now.add(-t);
+
+    for (var i = _model.myPositionHistoryTmp.length - 1; i >= 0; i--) {
+      final one = _model.myPositionHistoryTmp[i];
+      if (one.timestamp.isBefore(bt)) {
+        break;
+      }
+      locations.add(one);
+    }
+    if (locations.length > 1) {
+      for (var i = 0; i < locations.length; i++) {
+        if (i > 0) {
+          final p1 = locations[i];
+          final p2 = locations[i - 1];
+          disKm += p1.distance(p2).km;
+        }
+      }
+
+      final d = locations.last.timestamp.difference(locations[0].timestamp);
+
+      final speedMPerS =
+          disKm * 1000 / (d.inMilliseconds.toDouble().abs() / 1000);
+      _model.speedMPreS.value = speedMPerS;
+      if (speedMPerS > 1.1) {
+        // ---- 均值 -----
+        // var dSum = 0.0;
+        // var count = 0;
+        // for(var i=locations.length-1; i >=0 && i >= locations.length-3; i--){
+        //   final l1 = locations[i];
+        //   final l2 = locations[i-1];
+        //   dSum += l1.directionTo(l2);
+        //   count++;
+        // }
+        //
+        // return dSum/count;
+        // ---------------
+
+        final l1 = locations[locations.length-1];
+        var i = locations.length-4;
+        if(i< 0){
+          i=0;
+        }
+        final l2 = locations[i];
+        return l1.directionTo(l2);
+
+      }
+    }
+
+    return null;
+  }
+
+  @override
+  Future<void> close() async {
+    super.close();
+    compassListener?.cancel();
+    accelerometer?.cancel();
+  }
+}

+ 45 - 0
lib/service/map/plug_orientation2.dart

@@ -0,0 +1,45 @@
+import 'dart:async';
+import 'package:get/get.dart';
+import 'package:trackoffical_app/service/app.dart';
+import 'package:sensor/sensor.dart' as sensor;
+import 'compass_updater.dart';
+import 'plug.dart';
+
+typedef Orientation = sensor.Orientation;
+
+
+class PlugOrientation extends Plug{
+  PlugOrientation();
+  final _app = App.to;
+  final _angleSrcUpdater = CompassUpdater();
+  final orientation=Orientation().obs;
+  // /// 指北针弧度,移动时通过GPS判断
+  // final compassRadiansFused = 0.0.obs;
+  final compassRadiansSrc = 0.0.obs;
+  var accelerometerEvent = sensor.Orientation();
+  var compassRealNorthOffset = 0.0;
+
+  @override
+  Future<void> init() async{
+
+    listenStream(sensor.Sensor.orientationStream, (event) {
+      orientation.value = event;
+
+      var direction = event.z;
+      if (App.to.userProfile.gameSettingsRealNorth.value) {
+        direction += compassRealNorthOffset;
+      }
+
+      final src = _angleSrcUpdater.updateRadians(direction);
+      if(src!=null){
+        compassRadiansSrc.value = -src;
+      }
+    });
+  }
+
+  @override
+  Future<void> onClose() async{
+    _app.locationStop();
+  }
+}
+

+ 0 - 0
lib/view/app_need_update_view.dart → lib/view/app_need_update_view.dart.bk


+ 5 - 5
lib/view/home/dialog_special_warn.dart → lib/view/home/dialog_special_warn.dart.bk

@@ -4,9 +4,9 @@ import 'package:trackoffical_app/generated/assets.dart';
 import 'package:trackoffical_app/screen.dart';
 import 'package:trackoffical_app/screen.dart';
 import 'package:trackoffical_app/service/app.dart';
 import 'package:trackoffical_app/service/app.dart';
 import 'package:trackoffical_app/service/mock.dart';
 import 'package:trackoffical_app/service/mock.dart';
-import 'package:trackoffical_app/view/ingame/dialog/dialog_base.dart';
+// import 'package:trackoffical_app/view/ingame/dialog/dialog_base.dart';
 import '../../../styles/theme.dart';
 import '../../../styles/theme.dart';
-import '../ingame/dialog/dialog_button.dart';
+// import '../ingame/dialog/dialog_button.dart';
 
 
 
 
 class DialogSpecialWarn extends StatefulWidget {
 class DialogSpecialWarn extends StatefulWidget {
@@ -66,9 +66,9 @@ class DialogSpecialWarnState extends State<DialogSpecialWarn> {
                 Text('下次不再提醒', style: TextStyle(fontSize: 3.58.wp),),
                 Text('下次不再提醒', style: TextStyle(fontSize: 3.58.wp),),
               ])),
               ])),
           SizedBox(height: 4.0.wp),
           SizedBox(height: 4.0.wp),
-          dialogButton('我已阅读', () {
-            Get.back();
-          })
+          // dialogButton('我已阅读', () {
+          //   Get.back();
+          // })
         ]));
         ]));
   }
   }
 }
 }

+ 0 - 0
lib/view/home/guardian_view.dart → lib/view/home/guardian_view.dart.bk


+ 0 - 0
lib/view/home/home_gallery_view.dart → lib/view/home/home_gallery_view.dart.bk


+ 0 - 0
lib/view/home/home_map_view.dart → lib/view/home/home_map_view.dart.bk


+ 0 - 0
lib/view/home/home_save_user_info_view.dart → lib/view/home/home_save_user_info_view.dart.bk


+ 0 - 0
lib/view/home/under_guardian_view.dart → lib/view/home/under_guardian_view.dart.bk


+ 0 - 365
lib/view/ingame/bottom_bar.dart

@@ -1,365 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:get/get.dart';
-import 'package:trackoffical_app/service/game/game_model.dart';
-import 'package:trackoffical_app/styles/theme.dart';
-import 'package:trackoffical_app/utils.dart';
-import 'package:trackoffical_app/view/ingame/utils.dart';
-import '../../model/m_control_point.dart';
-import 'in_game_controller.dart';
-
-
-
-
-class BottomBar extends GetView<InGameController> {
-  BottomBar({super.key});
-
-
-  final _model = Get.find<GameModel>();
-
-  @override
-  Widget build(BuildContext context) {
-    return Obx(() {
-      final duration = controller.beginDurationStr;
-      final next = _model.nextPlanPoint;
-      final hrp = _model.heartRatePercent.value.round();
-      var color = hrp.toHRPColor();
-      var cpChecked = _model.validCPCount;
-
-      return SizedBox(
-        height: InGameController.bottomBarHeight,
-        width: context.width,
-        child: PageView(
-          scrollDirection: Axis.horizontal,
-          children: [
-            BottomBar1(
-                color: color,
-                duration: duration,
-                myPositionHistoryLenKm: _model.myPositionHistoryLen.value.km,
-                targetDistanceKm: controller.nextControlPointDistanceKm,
-                paceSecond: _model.paceSecondKm.value,
-                nextCp: next,
-                cpAll: _model.validCPAllNum,
-                cpChecked: cpChecked,
-                distance: _model.widgetDistance(fontSize: 21, withTrip: !controller.isInGameUISimplifyMode),
-                pace:  _model.widgetPace(fontSize: 21, withTrip: !controller.isInGameUISimplifyMode)),
-            BottomBar2(
-                color: color,
-                duration: duration,
-                cpAll: _model.validCPAllNum,
-                cpChecked: cpChecked,
-                hr: _model.heartRate.value,
-                hrp: hrp,
-                stepCount: _model.stepCount.value,
-                kCal: _model.kCal.value,
-                ck: _model.ck.value,
-                ei: _model.ei.value)
-          ],
-        )
-      ) ;
-    });
-  }
-}
-
-
-Widget wDuration(String duration) {
-  return Text(duration,
-      style: const TextStyle(fontSize: 20, fontFamily: 'sa-digital-number'));
-}
-
-
-
-Widget elemCp(MControlPoint? nextCp) {
-  Widget text;
-  const style = TextStyle(fontSize: 26, fontWeight: FontWeight.w700);
-  if (nextCp != null) {
-    text = nextCp.display(textStyle: style);
-    if (nextCp.areaId.isNotEmpty && nextCp.type == MControlPointType.nfc) {
-      text = Row(
-        mainAxisSize: MainAxisSize.min,
-        children: [
-          text,
-          Text(
-            ' (${nextCp.areaId})',
-            style: style,
-          )
-        ],
-      );
-    }
-  } else {
-    text = const Text('--', style: style, maxLines: 1);
-  }
-
-  return text;
-}
-
-Widget wKm(double? km, double fontSize, {FontWeight? fontWeight}) {
-  var unit = ' km';
-  var value = '--';
-
-  if(km != null){
-    var i = km;
-    if (km < 1) {
-      unit = ' m';
-      i *= 1000;
-    }
-    value = i.round().toString();
-  }
-
-  return RichText(
-      text: TextSpan(
-          text: value,
-          style: TextStyle(fontSize: fontSize, fontWeight: fontWeight?? FontWeight.w500),
-          children: [
-            TextSpan(
-              text: unit,
-              style: TextStyle(fontSize: fontSize* 0.5, fontWeight: FontWeight.w500))
-          ]
-      ));
-}
-
-class BottomBar1 extends StatelessWidget {
-  const BottomBar1({
-    super.key,
-    required this.color,
-    required this.duration,
-    required this.myPositionHistoryLenKm,
-    required this.targetDistanceKm,
-    required this.paceSecond,
-    required this.nextCp,
-    required this.cpAll,
-    required this.cpChecked,
-    required this.distance,
-    required this.pace,
-  });
-
-  final Color color;
-  final MControlPoint? nextCp;
-  final String duration;
-  final int cpAll;
-  final int cpChecked;
-  final double myPositionHistoryLenKm;
-  final double? targetDistanceKm;
-  final Duration paceSecond;
-  final Widget distance;
-  final Widget pace;
-
-  @override
-  Widget build(BuildContext context) {
-
-    return Stack(children: [
-      _BottomBarContainer(
-        color: color,
-        children: [
-          elemCp(nextCp),
-          wDuration(duration),
-          getElemDistance(),
-          wKm(targetDistanceKm, 26, fontWeight: FontWeight.w700),
-          Text('$cpChecked/$cpAll', style: const TextStyle(fontSize: 32)),
-          getElemPace()
-        ],
-      ),
-
-      Positioned(
-        left: 0,
-          top: 0,
-          child: getSmallTitle('目标')
-      ),
-      Positioned(
-          right: 0,
-          top: 0,
-          child: getSmallTitle('里程')
-      ),
-      Positioned(
-          left: 0,
-          bottom: 0,
-          child: getSmallTitle('点距')
-      ),
-      Positioned(
-          right: 0,
-          bottom: 0,
-          child: getSmallTitle('配速')
-      ),
-
-    ],) ;
-  }
-
-  Widget getElemDistance(){
-    return Padding(
-        padding: const EdgeInsets.only(left: 16, right: 16),
-        child: distance) ;
-  }
-  Widget getElemPace(){
-    return Padding(
-        padding: const EdgeInsets.only(left: 16, right: 16),
-        child: pace) ;
-  }
-}
-
-class BottomBar2 extends StatelessWidget {
-  const BottomBar2({
-    super.key,
-    required this.color,
-    required this.duration,
-    required this.cpAll,
-    required this.cpChecked,
-    required this.hr,
-    required this.hrp,
-    required this.stepCount,
-    required this.kCal,
-    required this.ck,
-    required this.ei,
-  });
-
-  final Color color;
-  final int hr;
-  final int hrp;
-  final String duration;
-  final int cpAll;
-  final int cpChecked;
-  final int stepCount;
-  final double kCal;
-  final double ck;
-  final double ei;
-
-  Widget wHrp() {
-    return Row(
-      mainAxisSize: MainAxisSize.min,
-      crossAxisAlignment: CrossAxisAlignment.start,
-      children: [
-        Text('$hrp',
-            style: const TextStyle(fontSize: 43, fontWeight: FontWeight.w700)),
-        const Text('%',
-            style: TextStyle(fontSize: 20, fontWeight: FontWeight.w700))
-      ],
-    );
-  }
-
-  Widget wHr() {
-    return Row(
-      mainAxisSize: MainAxisSize.min,
-      crossAxisAlignment: CrossAxisAlignment.start,
-      children: [
-        Text('$hr',
-            style: const TextStyle(fontSize: 43, fontWeight: FontWeight.w700)),
-        Padding(
-            padding: const EdgeInsets.only(top: 5),
-            child: Image.asset('assets/images/ic_heart.png', height: 14.4))
-      ],
-    );
-  }
-
-
-
-  @override
-  Widget build(BuildContext context) {
-    return _BottomBarContainer(
-      color: color,
-      children: [
-        wHrp(),
-        wDuration(duration),
-        wHr(),
-        Row(
-          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
-          children: [
-            wSport('$stepCount', 'assets/images/ic_step_count.png'),
-            const SizedBox(width: 12),
-            wSport(kCal.toStringAsFixed(1), 'assets/images/ic_kcal.png'),
-          ],
-        ),
-        Text('$cpChecked/$cpAll', style: const TextStyle(fontSize: 32)),
-        Row(
-          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
-          children: [
-            wSport(ck.toStringAsFixed(1), 'assets/images/ic_ck.png'),
-            const SizedBox(width: 12),
-            wSport(ei.round().toString(), 'assets/images/ic_ei.png'),
-          ],
-        ),
-      ],
-    );
-  }
-}
-
-class _BottomBarContainer extends StatelessWidget {
-  const _BottomBarContainer({required this.children, required this.color});
-
-  final List<Widget> children;
-  final Color color;
-
-  @override
-  Widget build(BuildContext context) {
-    return DefaultTextStyle(
-        style: const TextStyle(color: Colors.white),
-        child: Container(
-          width: context.width,
-          height: InGameController.bottomBarHeight,
-          decoration: BoxDecoration(
-              color: color,
-              image: const DecorationImage(
-                  image: AssetImage('assets/images/bk_ingame_bottom_bar.png'))),
-          child: Column(
-            children: [
-              Expanded(
-                  child: Row(
-                children: [
-                  Expanded(flex: 4, child: Center(child: children[0])),
-                  Expanded(
-                    flex: 6,
-                    child: Center(child: children[1]),
-                  ),
-                  Expanded(flex: 4, child: Center(child: children[2])),
-                ],
-              )),
-              Expanded(
-                  child: Row(
-                children: [
-                  Expanded(flex: 4, child: Center(child: children[3])),
-                  Expanded(flex: 6, child: Center(child: children[4])),
-                  Expanded(flex: 4, child: Center(child: children[5])),
-                ],
-              )),
-            ],
-          ),
-        ));
-  }
-}
-
-void main() async {
-  final b1 = BottomBar1(
-    color: Colors.blue,
-    nextCp: MControlPoint()
-      ..isStart = true
-      ..areaId = 'A51',
-    targetDistanceKm: 1.234,
-    duration: "00:00:00",
-    cpAll: 18,
-    cpChecked: 7,
-    myPositionHistoryLenKm: 3.1,
-    paceSecond: 380.seconds,
-    distance: const SizedBox(),
-    pace: const SizedBox(),
-  );
-  final b2 = const BottomBar2(
-      color: Colors.blue,
-      duration: '00:00:00',
-      cpAll: 18,
-      cpChecked: 7,
-      hr: 123,
-      hrp: 80,
-      stepCount: 0,
-      kCal: 11231,
-      ck: 2344,
-      ei: 1231);
-
-  var bottom = b1;
-
-  runApp(GetMaterialApp(
-      theme: appThemeData(),
-      home: Scaffold(
-          body: Column(
-        children: [
-          Spacer(),
-          bottom,
-        ],
-      ))));
-}

+ 0 - 372
lib/view/ingame/button_bar.dart

@@ -1,372 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:get/get.dart';
-import 'package:trackoffical_app/generated/assets.dart';
-import 'package:trackoffical_app/service/game/game.dart';
-import 'package:trackoffical_app/service/game/game_model.dart';
-import 'package:trackoffical_app/view/game_settings.dart';
-import 'package:trackoffical_app/view/ingame/route_planning.dart';
-import 'utils.dart';
-import 'button_punch.dart';
-import 'info_view.dart';
-import 'settings_view.dart';
-import 'package:trackoffical_app/widget/compass2.dart';
-import '../../styles/theme.dart';
-import 'in_game_controller.dart';
-
-class MButtonBar extends StatefulWidget {
-  const MButtonBar({
-    super.key,
-    required this.isShowCheckCPButton,
-    required this.isCheckCPButtonEnable,
-  });
-
-  final bool isShowCheckCPButton;
-  final bool isCheckCPButtonEnable;
-
-  @override
-  State<StatefulWidget> createState() {
-    return ButtonBarState();
-  }
-}
-
-enum _ExpandState {
-  hide,
-  middle,
-  all,
-}
-
-class ButtonBarState extends State<MButtonBar> {
-  var state = _ExpandState.middle;
-  final controller = Get.find<InGameController>();
-  final service = GameService.to;
-  final model = Get.find<GameModel>();
-
-  @override
-  void initState() {
-    super.initState();
-
-  }
-
-  void onButtonMore() {
-    setState(() {
-      var i = state.index + 1;
-      if (i >= _ExpandState.values.length) {
-        i = 0;
-      }
-      state = _ExpandState.values[i];
-    });
-  }
-
-  void onLockScreenCenterToMyPosition() {
-    setState(() {
-      if (!model.isLockScreenCenterToMyPositionSystem) {
-        service.showLocation();
-      }
-
-      model.isLockScreenCenterToMyPosition.value =
-          !model.isLockScreenCenterToMyPosition.value;
-    });
-  }
-
-  void onRotateAt() {
-    setState(() {
-      controller.isMapRotateAtCompassCenter.value =
-          !controller.isMapRotateAtCompassCenter.value;
-    });
-
-    controller.flushRotateCenter();
-  }
-
-  void btnMore(List<Widget> col) {
-    var moreSrc = 'assets/images/btn_more1.png';
-    if (state == _ExpandState.middle) {
-      moreSrc = 'assets/images/btn_more2.png';
-    }
-    if (state == _ExpandState.all) {
-      moreSrc = 'assets/images/btn_more3.png';
-    }
-    col.add(_Button(icon: Image.asset(moreSrc), onPressed: onButtonMore));
-  }
-
-  // 屏幕移至站立点
-  void btnMyLocation(List<Widget> col) {
-    col.add(_Button(
-        icon: Image.asset('assets/images/btn_location.png'),
-        disableSrc: 'assets/images/btn_location_disable.png',
-        onPressed: model.isEnableUserLocation ? service.showLocation : null));
-  }
-
-  // 跳点
-  void btnSkipCp(List<Widget> col) {
-    // if (model.isAllowedPassCP) {
-    if (true) {
-      col.add(_Button(
-        icon: Image.asset('assets/images/btn_skip_cp.png'),
-        disableSrc: Assets.imagesBtnSkipCpDisable,
-      ));
-    }
-  }
-
-  // 路线规划
-  void btnPathPlanning(List<Widget> col) {
-    // if (model.isAllowedPassCP) {
-    if (true) {
-      col.add(Obx(() => _Button(
-            icon: Image.asset('assets/images/btn_path_planning.png'),
-            disableSrc: Assets.imagesBtnPathPlanningDisable,
-            onPressed:
-                model.startAt != null ? () => dialogRoutePlanning() : null,
-          )));
-    }
-  }
-
-  // 地图旋转中心
-  void btnMapRotateCenter(List<Widget> col) {
-    var rotateSrc = 'assets/images/btn_rotate_at1.png';
-    if (controller.isMapRotateAtCompassCenter.value) {
-      rotateSrc = 'assets/images/btn_rotate_at2.png';
-    }
-    col.add(_Button(icon: Image.asset(rotateSrc), onPressed: onRotateAt));
-  }
-
-  // 锁定旋转中心
-  void btnLockRotateCenter(List<Widget> col) {
-    if (model.isAlwaysShowMyLocation) {
-      var src = 'assets/images/btn_unlock.png';
-      if (model.isLockScreenCenterToMyPosition.value) {
-        src = 'assets/images/btn_locked.png';
-      }
-
-      col.add(_Button(
-          icon: Image.asset(src),
-          disableSrc: 'assets/images/btn_unlock_disable.png',
-          onPressed: model.isEnableUserLocation
-              ? onLockScreenCenterToMyPosition
-              : null));
-    }
-  }
-
-  onMapModeSwitch() {
-    service.mapStatus.mapModeSwitch();
-    service.showNextPoint();
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    final col1 = <Widget>[];
-
-    btnMore(col1);
-
-    if (state == _ExpandState.middle || state == _ExpandState.all) {
-      // 标定地图方式
-      col1.add(_Button(
-          icon: Image.asset('assets/images/btn_map_rotate.png'),
-          onPressed: onMapModeSwitch));
-      btnMyLocation(col1);
-      btnLockRotateCenter(col1);
-      col1.addAll([
-        // 行动轨迹
-        _Button(
-            icon: Image.asset('assets/images/btn_trajectory.png'),
-            disableSrc: 'assets/images/btn_trajectory_disable.png',
-            onPressed: model.isEnableUserLocation
-                ? () => setState(() {
-                      model.isShowTrajectory.value =
-                          !model.isShowTrajectory.value;
-                    })
-                : null,
-            isSelected: model.isShowTrajectory.value),
-
-        // 亮度
-        _Button(
-          icon: Image.asset('assets/images/btn_brightness.png'),
-          onPressed: _onBrightness,
-          isSelected: controller.isBrightnessMax,
-        ),
-      ]);
-    }
-
-    final col2 = <Widget>[];
-    final col3 = <Widget>[];
-    if (state == _ExpandState.all) {
-      col2.addAll([
-        // 指北针大小
-        _Button(
-            icon: Image.asset('assets/images/btn_compass_size.png'),
-            onPressed: controller.onSwitchCompassSize),
-
-        // 指北针显示
-        _Button(
-          icon: Image.asset('assets/images/btn_compass.png'),
-          onPressed: () => setState(() {
-            controller.showCompassSwitch();
-          }),
-          isSelected: service.isShowCompass.value,
-        ),
-        // 指南针样式
-        _Button(
-            icon: Image.asset('assets/images/btn_compass_level.png'),
-            onPressed: onClickCompassLevel),
-
-        // 是否显示下一点方向
-        _Button(
-          icon: Image.asset('assets/images/btn_next_cp.png'),
-          onPressed: () => setState(() {
-            controller.isShowNextCPRadians.value =
-                !controller.isShowNextCPRadians.value;
-          }),
-          isSelected: controller.isShowNextCPRadians.value,
-        ),
-      ]);
-
-      btnSkipCp(col2);
-
-      col2.add(_Button(
-          icon: Image.asset('assets/images/btn_past_cp.png'),
-          onPressed: (){}
-          // showCheckedPoints
-      ));
-
-      col3.addAll([
-        // 图例
-        _Button(
-            icon: Image.asset('assets/images/btn_info.png'),
-            onPressed: _showInfo),
-        // 设置
-        _Button(
-            icon: Image.asset('assets/images/btn_settings.png'),
-            onPressed: _toSettings),
-
-        // 显示标尺
-        _Button(
-          icon: Image.asset('assets/images/btn_ruler.png'),
-          onPressed: () => setState(() {
-            controller.isShowRuler.value = !controller.isShowRuler.value;
-          }),
-          isSelected: controller.isShowRuler.value,
-        ),
-      ]);
-
-      btnMapRotateCenter(col3);
-      btnPathPlanning(col3);
-
-      // 退赛
-      col3.add(_Button(
-          icon: Image.asset('assets/images/btn_exit.png'),
-          onPressed: () => onButtonExit(controller)));
-    }
-
-    final children = <Widget>[
-      Row(
-        children: [
-          Column(
-            children: col1,
-          ),
-          const Spacer(),
-          Column(children: col2),
-          Column(children: col3)
-        ],
-      ),
-    ];
-    if (widget.isShowCheckCPButton) {
-      final color = widget.isCheckCPButtonEnable ? Colors.black : Colors.grey;
-
-      children.addAll([
-        const Spacer(),
-        Row(
-          children: [
-            const Spacer(),
-            ButtonPunch(
-              onPressed: widget.isCheckCPButtonEnable
-                  ? controller.onCheckControlPoint
-                  : null,
-              isWarn: controller.isCheckCPButtonWarn,
-            ),
-          ],
-        ),
-        const SizedBox(height: 12),
-      ]);
-    }
-
-    return Padding(
-        padding: const EdgeInsets.only(left: 12, right: 12),
-        child: Column(
-          children: children,
-        ));
-  }
-
-  void _onBrightness() async {
-    await controller.setIsBrightnessMax(!controller.isBrightnessMax);
-    setState(() {});
-  }
-
-  Future<void> _toSettings() async {
-    await controller.toSettings();
-    setState(() {});
-  }
-
-  void _showInfo() {
-    Get.to(() => InfoView());
-  }
-
-  void onClickCompassLevel() {
-    var l = controller.compassLevel.value;
-    l++;
-    if (l > Compass2.levelMax) {
-      l = Compass2.levelMin;
-    }
-    controller.compassLevel.value = l;
-  }
-}
-
-class _Button extends StatelessWidget {
-  const _Button({
-    required this.icon,
-    this.onPressed,
-    this.isSelected = false,
-    this.disableSrc,
-  });
-
-  final bool isSelected;
-  final Widget icon;
-  final VoidCallback? onPressed;
-  final String? disableSrc;
-
-  @override
-  Widget build(BuildContext context) {
-    const s = 46.0;
-
-    final children = <Widget>[
-      SizedBox(
-          width: s,
-          height: s,
-          child: onPressed != null ? icon : Image.asset(disableSrc!))
-    ];
-
-    if (isSelected && onPressed != null) {
-      children.add(Image.asset(
-        'assets/images/btn_boader.png',
-        width: s,
-        height: s,
-      ));
-    }
-
-    return GestureDetector(
-      onTap: onPressed,
-      child: Stack(
-        children: children,
-      ),
-    );
-  }
-}
-
-void main() async {
-  runApp(GetMaterialApp(
-      theme: appThemeData(),
-      home: const Scaffold(
-        body: MButtonBar(
-          isShowCheckCPButton: true,
-          isCheckCPButtonEnable: true,
-        ),
-      )));
-}

+ 0 - 169
lib/view/ingame/button_punch.dart

@@ -1,169 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:get/get.dart';
-import 'package:trackoffical_app/generated/assets.dart';
-import 'package:trackoffical_app/service/app.dart';
-import 'package:trackoffical_app/view/ingame/in_game_controller.dart';
-import 'package:rive/rive.dart';
-import 'package:vibration/vibration.dart';
-
-class ButtonPunch extends StatefulWidget {
-  const ButtonPunch({
-    super.key,
-    required this.onPressed,
-    required this.isWarn,
-  });
-
-  final VoidCallback? onPressed;
-  final bool isWarn;
-
-  @override
-  State<StatefulWidget> createState() {
-    return ButtonPunchState();
-  }
-}
-
-class ButtonPunchState extends State<ButtonPunch>
-    with SingleTickerProviderStateMixin {
-  late AnimationController _animationController;
-  late Animation<Color?> _animation;
-  var _isActive = true;
-
-  @override
-  void initState() {
-    super.initState();
-
-    _animationController = AnimationController(
-      vsync: this,
-      duration: const Duration(milliseconds: 500),
-      reverseDuration: const Duration(milliseconds: 500),
-    )..repeat(reverse: true);
-    _animation = ColorTween(begin: Colors.white, end: Colors.red)
-        .animate(_animationController)
-        ..addListener(() {
-        setState(() {
-          // The state that has changed here is the animation object’s value.
-        });
-      });
-
-    loopVibration();
-  }
-
-  Future<void> loopVibration() async{
-    final c = Get.find<InGameController>();
-    while(_isActive){
-      await Future.delayed(500.milliseconds);
-
-      if(widget.isWarn && c.isEnableGameVibrate.value){
-        if (await Vibration.hasCustomVibrationsSupport()==true) {
-          Vibration.vibrate(duration: 100, repeat: 1);
-        } else {
-          Vibration.vibrate();
-        }
-      }
-
-    }
-  }
-
-
-  @override
-  void didUpdateWidget(covariant ButtonPunch oldWidget) {
-    super.didUpdateWidget(oldWidget);
-
-    final oldEnabled = oldWidget.onPressed != null;
-    final newEnabled = widget.onPressed != null;
-
-    if (oldEnabled != newEnabled) {
-      if (newEnabled) {
-        _animationController.repeat(reverse: true);
-      } else {
-        _animationController.stop();
-      }
-    }
-  }
-
-  @override
-  void dispose() {
-    _animationController.dispose();
-    _isActive=false;
-    super.dispose();
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    final image = widget.onPressed != null? 'assets/images/btn_punch.png': 'assets/images/btn_punch_disable.png';
-
-    final boxShadow = <BoxShadow>[];
-    final children = <Widget>[];
-    if(widget.isWarn){
-      boxShadow.add(BoxShadow(
-          color: Colors.red.withAlpha(150),
-          offset: const Offset(0.0, 0.0), //阴影y轴偏移量
-          blurRadius: 6, //阴影模糊程度
-          spreadRadius: widget.onPressed!= null? 2: 1 //阴影扩散程度
-      ));
-      children.add(const RiveAnimation.asset(Assets.imagesAmPunchButtonFlash, fit: BoxFit.fill));
-    }else{
-      boxShadow.add(BoxShadow(
-          color: Colors.grey.withAlpha(150),
-          offset: const Offset(2.0, 2.0), //阴影y轴偏移量
-          blurRadius: 6, //阴影模糊程度
-          spreadRadius: widget.onPressed!= null? 5: 1 //阴影扩散程度
-      ));
-    }
-
-    children.add(GestureDetector(
-      onTap: widget.onPressed,
-      child: Container(
-        width: 56,
-        height: 56,
-        decoration: BoxDecoration(
-          color: Colors.white,
-          image: DecorationImage(
-              image: AssetImage(image)),
-          borderRadius: BorderRadius.circular(28),
-          boxShadow: boxShadow,
-        ),
-      ),
-    ));
-
-    return SizedBox(height: 90, width: 90, child: Stack(
-      alignment: Alignment.center,
-      children: children,
-    ) ) ;
-    // return GestureDetector(
-    //   onTap: widget.onPressed,
-    //   child: Container(
-    //     width: 56,
-    //     height: 56,
-    //     decoration: BoxDecoration(
-    //       color: Colors.white,
-    //       image: DecorationImage(
-    //           image: AssetImage(image)),
-    //       borderRadius: BorderRadius.circular(28),
-    //       boxShadow: [
-    //         BoxShadow(
-    //             color: widget.isWarn? _animation.value ?? Colors.grey: Colors.grey.withAlpha(150),
-    //             offset: widget.isWarn? const Offset(0, 0):const Offset(2.0, 2.0), //阴影y轴偏移量
-    //             blurRadius: 6, //阴影模糊程度
-    //             spreadRadius: widget.onPressed!= null? 5: 1 //阴影扩散程度
-    //             )
-    //       ],
-    //     ),
-    //   ),
-    // );
-  }
-}
-void main() async {
-  runApp(Container(
-    color: Colors.white,
-    child: Column(
-      children: [
-        const Spacer(),
-        ButtonPunch(
-          onPressed: () {  },
-          isWarn: false,
-        )
-      ],
-    ) )
-  ) ;
-}

+ 0 - 81
lib/view/ingame/checked_cp_record.dart

@@ -1,81 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:trackoffical_app/model/m_control_point.dart';
-import 'package:trackoffical_app/utils.dart';
-
-
-class CheckedCPRecord extends StatelessWidget{
-  const CheckedCPRecord({
-    super.key,
-    required this.data
-  });
-
-  final List<MControlPoint> data;
-
-
-  @override
-  Widget build(BuildContext context) {
-    return ListView.builder(
-      itemCount: data.length,
-        itemBuilder: (context, index){
-          return _elem(context, data[index]);
-        }
-    );
-  }
-}
-
-Widget _elem(BuildContext context, MControlPoint data){
-  const disableColor = Color(0xffaaaaaa);
-  const enableColor = Color(0xff333333);
-  var result = '已完成';
-  Color resultColor = Colors.green;
-  final color = data.isUnchecked? disableColor: enableColor;
-  Color? iconColor;
-  var textTime = data.checkAfterPrev.toMinSecondString();
-
-
-  var imageSrc = 'assets/images/ic_cp.png';
-  if(data.isStart){
-    imageSrc = 'assets/images/ic_cp_start.png';
-    textTime = '';
-  }
-  if(data.isFinish){
-    imageSrc = 'assets/images/ic_cp_finish_uncheck.png';
-    textTime = '';
-  }
-  if(!data.isSuccess){
-    result = '错误';
-    resultColor = const Color(0xffff6203);
-  }
-  if(data.isUnchecked){
-    iconColor = disableColor;
-    result = '未打点';
-    resultColor = disableColor;
-    textTime='';
-  }
-
-
-
-  var text = data.snString.isNotEmpty? '${data.snString}点': '';
-  if(data.areaId.isNotEmpty){
-    text += '(${data.areaId})';
-  }
-
-
-  final style = TextStyle(
-      fontSize: 15.24, fontWeight: FontWeight.w500, color: color);
-
-
-  return Padding(padding: const EdgeInsets.only(bottom: 12), child: Row(
-    crossAxisAlignment: CrossAxisAlignment.center,
-    children: [
-      Image.asset(imageSrc, color: iconColor, height: 21.19, width: 21.19),
-      const SizedBox(width: 6),
-      Expanded(flex:4, child: Text(text, style: style, textAlign: TextAlign.start, maxLines: 1)),
-      Expanded(flex:3, child: Text(textTime, style: style, textAlign: TextAlign.start, maxLines: 1)),
-      SizedBox(
-          width: 60,
-          child: Text(result, style: style.copyWith(fontSize: 17.42, color: resultColor))
-      ),
-    ],
-  )) ;
-}

+ 0 - 0
lib/view/ingame/common.dart


+ 0 - 155
lib/view/ingame/dialog/dialog_base.dart

@@ -1,155 +0,0 @@
-import 'dart:async';
-import 'package:flutter/material.dart';
-import 'package:get/get.dart';
-import 'package:trackoffical_app/logger.dart';
-import 'package:trackoffical_app/screen.dart';
-import '../../../generated/assets.dart';
-
-class DialogBase extends DialogBaseOffCount {
-  const DialogBase({super.key, Duration? offAfter, required Widget  child}) : super(
-     offAfter: offAfter, child: child
-  );
-  @override
-  State<StatefulWidget> createState() {
-    return DialogBaseState();
-  }
-}
-
-
-
-
-class DialogBaseState extends DialogBaseOffCountState<DialogBase> {
-
-  @override
-  Widget build(BuildContext context) {
-    final style = (context.textTheme.titleLarge ?? const TextStyle())
-        .copyWith(color: const Color(0xff333333), fontSize: 41.98.rpx);
-
-    final children = <Widget>[
-      Container(
-          margin: EdgeInsets.only(left: 47.71.rpx, right: 47.71.rpx),
-          padding:
-              EdgeInsets.fromLTRB(5.85.wp, 9.67.wp, 5.85.wp, 9.67.wp),
-          decoration: BoxDecoration(
-              color: const Color(0xe6ffffff),
-              borderRadius: BorderRadius.circular(17.18.rpx)),
-          child: widget.child)
-    ];
-
-    if (widget.offAfter != null) {
-      children.addAll([
-        Obx(() => offCount(secondCount.value))
-      ]);
-    }
-
-    return DefaultTextStyle(
-        style: style,
-        child: Container(
-          width: context.width,
-          height: context.height,
-          color: const Color(0xB8000000),
-          alignment: Alignment.center,
-          child: Center(
-            child: Column(
-              mainAxisSize: MainAxisSize.min,
-              children: children,
-            ),
-          ),
-        ));
-  }
-}
-
-abstract class DialogBaseOffCount extends StatefulWidget{
-  const DialogBaseOffCount({
-    super.key,
-    this.offAfter,
-    required this.child});
-
-  final Duration? offAfter;
-  final Widget child;
-
-}
-
-abstract  class  DialogBaseOffCountState <T extends DialogBaseOffCount> extends State<T>{
-  final Rx<int?> secondCount = Rx(null);
-  Timer? _timer;
-  DateTime _createAt = DateTime.now();
-  var isActive = true;
-  void onStop(){
-    if(mounted){
-      debug('back: ${widget.runtimeType}');
-      Get.back();
-    }
-  }
-
-  @override
-  void initState() {
-    super.initState();
-
-
-
-    final offAfter = widget.offAfter;
-    _createAt = DateTime.now();
-
-    if (offAfter != null) {
-      _timer = Timer.periodic(100.milliseconds, (timer) {
-        final d = DateTime.now().difference(_createAt);
-        secondCount.value =offAfter.inSeconds - (d.inMilliseconds / 1000).floor();
-
-        if (d >= offAfter) {
-          onStop();
-        }
-      });
-    }
-  }
-
-  @override
-  void dispose() {
-    super.dispose();
-    debug('${widget.runtimeType} dispose()');
-    isActive = false;
-    _timer?.cancel();
-  }
-}
-
-Widget offCount(int? secondCount){
-  return Column(
-    mainAxisSize: MainAxisSize.min,
-    children: [
-      SizedBox(height: 50.0.rpx),
-      Text(
-        secondCount?.toString() ?? '',
-        style: TextStyle(fontSize: 150.0.rpx, color: const Color(0xffff870d)),
-      )
-    ],
-  );
-}
-
-Widget dialogTitle(String title, Color titleColor, Widget content,
-    {Duration? offAfter}) {
-  return  DialogBase(
-    offAfter: offAfter,
-    child: Column(
-      mainAxisSize: MainAxisSize.min,
-      children: [
-        Text(title, style: TextStyle(color: titleColor, fontSize: 55.07.rpx, fontWeight: FontWeight.w700)),
-        SizedBox(height: 32.1.rpx),
-        content
-      ],
-    ),
-  ) ;
-}
-
-Widget bean(int count, double fontSize) {
-  return Row(
-    mainAxisSize: MainAxisSize.min,
-    crossAxisAlignment: CrossAxisAlignment.end,
-    children: [
-      Image.asset(Assets.imagesIcBean, height: fontSize * 2.2, ),
-      Text(
-        ' X $count',
-        style: TextStyle(color: const Color(0xffaaaaaa), fontSize: fontSize),
-      )
-    ],
-  );
-}

+ 0 - 23
lib/view/ingame/dialog/dialog_button.dart

@@ -1,23 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:trackoffical_app/screen.dart';
-
-Widget dialogButton(String text, VoidCallback onPressed, {Color? color}) {
-  return Container(
-      margin: EdgeInsets.only(left: 78.24.rpx, right: 78.24.rpx),
-      height: 97.33.rpx,
-      width: double.infinity,
-      child: ConstrainedBox(
-          constraints: BoxConstraints(
-            maxWidth: 498.09.rpx,
-          ),
-          child: FilledButton(
-              onPressed: onPressed,
-              style: FilledButton.styleFrom(
-                shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(11.45.rpx)),
-              ),
-
-              child: Text(
-                text,
-                style: TextStyle(fontSize: 5.0.wp),
-              ))));
-}

+ 0 - 375
lib/view/ingame/dialog/dialog_check_rich.dart

@@ -1,375 +0,0 @@
-import 'dart:convert';
-
-import 'package:assets_audio_player/assets_audio_player.dart';
-import 'package:flutter/material.dart';
-import 'package:get/get.dart';
-import 'package:trackoffical_app/generated/assets.dart';
-import 'package:trackoffical_app/model/m_control_point.dart';
-import 'package:trackoffical_app/screen.dart';
-import 'package:trackoffical_app/utils.dart';
-import '../../../model/cp_extra_info.dart';
-import '../../../model/cp_extra_info_choice_question.dart';
-import '../../../styles/theme.dart';
-import 'dialog_base.dart';
-
-class DialogCheckRich extends StatefulWidget {
-  const DialogCheckRich(
-      {super.key, required this.point, required this.offAfter});
-
-  final Duration offAfter;
-  final MControlPoint point;
-
-  @override
-  State<StatefulWidget> createState() {
-    return DialogCheckRichState();
-  }
-}
-
-class DialogCheckRichState extends State<DialogCheckRich> {
-  Duration? offAfter;
-  var isActive = true;
-  final createAt = DateTime.now();
-  int? selectedIndex;
-  var isFinish = false;
-  var beanCount = 1;
-  final _audioPlayer = AssetsAudioPlayer.newPlayer();
-
-  @override
-  void initState() {
-    super.initState();
-    workCount();
-  }
-
-  @override
-  void dispose() {
-    isActive = false;
-    _audioPlayer.dispose();
-    super.dispose();
-  }
-
-
-  void _setFinish(){
-    setState(() {
-      isFinish = true;
-    });
-
-    _audioPlayer.open(
-      Audio(Assets.soundAfterAnswer),
-      autoStart: true,
-      showNotification: false,
-    );
-
-    3.seconds.delay().then((value){
-      if(isActive && Get.isOverlaysOpen){
-        Get.back();
-      }
-    });
-  }
-
-  Future<void> workCount() async {
-    while (isActive) {
-      if (isFinish) {
-        return;
-      }
-
-      final offAfter = DateTime.now().difference(createAt);
-      setState(() {
-        this.offAfter = offAfter;
-      });
-      if (offAfter > widget.offAfter) {
-        _setFinish();
-      }
-      await Future.delayed(100.milliseconds);
-    }
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    return isFinish ? wFinish() :  DefaultTextStyle(
-        style: context.textTheme.titleLarge ??
-            const TextStyle(), child: wMain());
-  }
-
-  Widget wMain() {
-    final extraInfo = widget.point.extraInfo;
-    final mainHeight = extraInfo != null ? 261.45.rpx : 358.78.rpx;
-    final point = widget.point;
-    final style = context.textTheme.titleLarge ??
-        const TextStyle().copyWith(
-            color: const Color(0xff333333),
-            fontSize: 61.0.rpx,
-            fontWeight: FontWeight.w700);
-    var title = point.snString.isNotEmpty ? '${point.snString}点' : '';
-    if (point.areaId.isNotEmpty) {
-      title += '(${point.areaId})';
-    }
-
-    var imageSrc = 'assets/images/ic_cp.png';
-    if (point.isStart) {
-      imageSrc = 'assets/images/ic_cp_start.png';
-    }
-    if (point.isFinish) {
-      imageSrc = 'assets/images/ic_cp_finish.png';
-    }
-
-    final children = <Widget>[];
-
-    if (extraInfo != null) {
-      children.add(wExtraInfo(extraInfo, mainHeight));
-    }
-
-    children.add(Container(
-      height: mainHeight,
-      margin: EdgeInsets.only(left: 47.71.rpx, right: 47.71.rpx),
-      decoration: BoxDecoration(
-          color: Colors.white,
-          borderRadius: BorderRadius.circular(17.18.rpx),
-          boxShadow: [
-            BoxShadow(
-              color: const Color(0x29000000),
-              offset: Offset(5.73.rpx, 5.73.rpx),
-              blurRadius: 11.45.rpx,
-              spreadRadius: 11.45.rpx,
-            )
-          ]),
-      padding: EdgeInsets.only(
-          left: 60.0.rpx, right: 60.0.rpx, top: 20.0.rpx, bottom: 20.0.rpx),
-      child: Column(
-        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
-        crossAxisAlignment: CrossAxisAlignment.start,
-        children: [
-          RichText(
-              text: TextSpan(text: '打点成功', style: style, children: [
-            TextSpan(
-                text: ' +${widget.point.checkAfterPrev.toMinSecondString()}',
-                style:
-                    style.copyWith(color: Colors.orange, fontSize: 30.53.rpx))
-          ])),
-          Row(
-            crossAxisAlignment: CrossAxisAlignment.end,
-            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-            children: [
-              Row(
-                mainAxisSize: MainAxisSize.min,
-                children: [
-                  Image.asset(imageSrc, height: 37.18.rpx),
-                  SizedBox(width: 15.3.rpx),
-                  Text(title, style: style.copyWith(fontSize: 30.5.rpx))
-                ],
-              ),
-              bean(1, 30.53.rpx),
-            ],
-          )
-        ],
-      ),
-    ));
-
-    int? second;
-    if (offAfter != null) {
-      second =
-          ((widget.offAfter.inMilliseconds - offAfter!.inMilliseconds) / 1000)
-              .ceil();
-    }
-
-    return GestureDetector(
-      // onTap: onBack,
-      child: Container(
-        width: context.width,
-        height: context.height,
-        color: const Color(0xB8000000),
-        alignment: Alignment.center,
-        child: Center(
-          child: Column(
-            mainAxisSize: MainAxisSize.min,
-            children: [
-              Stack(
-                children: children,
-              ),
-              SizedBox(height: 50.0.rpx),
-              Text(
-                second?.toString() ?? '',
-                style: context.textTheme.titleLarge?.copyWith(
-                    fontSize: 150.0.rpx, color: const Color(0xffff870d)),
-              )
-            ],
-          ),
-        ),
-      ),
-    );
-  }
-
-  Widget wFinish() {
-    return GestureDetector(
-      onTap: onBack,
-      child: Container(
-          width: context.width,
-          height: context.height,
-          color: const Color(0xB8000000),
-          alignment: Alignment.center,
-          child: Center(
-              child: DefaultTextStyle(
-                  style: context.textTheme.titleLarge ??
-                      const TextStyle().copyWith(
-                          color: const Color(0xffa0a0a0), fontSize: 45.8.rpx),
-                  child: Column(mainAxisSize: MainAxisSize.min, children: [
-                    bean(beanCount, 74.43.rpx),
-                    SizedBox(height: 48.9.rpx),
-                    Text(
-                      '共获得$beanCount个百味豆',
-                      style: const TextStyle(color: Color(0xffa0a0a0)),
-                    )
-                  ])))),
-    );
-  }
-
-  Future<void> onBack() async {
-    Get.back();
-  }
-
-  Widget wExtraInfo(CPExtraInfo extraInfo, double mainHeight) {
-    Widget child;
-
-    if (extraInfo is CPExtraInfoChoiceQuestion) {
-      child = wExtraInfoChoiceQuestion(extraInfo);
-    } else {
-      throw UnimplementedError('wExtraInfo: $extraInfo 未实现');
-    }
-
-    return Container(
-      margin: EdgeInsets.only(left: 64.8.rpx, right: 64.8.rpx),
-      padding: EdgeInsets.only(
-          left: 36.8.rpx,
-          right: 36.8.rpx,
-          top: mainHeight + 64.0.rpx,
-          bottom: 40.0.rpx),
-      decoration: BoxDecoration(
-          color: Colors.white, borderRadius: BorderRadius.circular(17.18.rpx)),
-        // child: child,
-      child: DefaultTextStyle(
-        style: context.textTheme.titleLarge ??
-            const TextStyle().copyWith(
-                color: Colors.black,
-                fontSize: 41.98.rpx,
-                fontWeight: FontWeight.w700),
-        child: child,
-      ),
-    );
-  }
-
-  Widget wExtraInfoChoiceQuestion(CPExtraInfoChoiceQuestion extraInfo) {
-    final answers = <Widget>[];
-    var ascii = 65;
-
-    for (var i = 0; i < extraInfo.answers.length; i++) {
-      final one = extraInfo.answers[i];
-      final sn = const Utf8Codec().decode([ascii]);
-      final selected = i == selectedIndex;
-
-      answers.add(GestureDetector(
-          onTap: () async {
-            if (selectedIndex == null) {
-              setState(() {
-                selectedIndex = i;
-              });
-
-              if (i == extraInfo.rightIndex) {
-                beanCount += extraInfo.beanCount;
-              }
-              widget.point.userAnswerIndex = selectedIndex;
-              widget.point.isAnswerCorrect =
-                  selectedIndex == extraInfo.rightIndex;
-
-              await 1.seconds.delay();
-
-              _setFinish();
-            }
-          },
-          child: Container(
-              padding: EdgeInsets.only(top: 15.0.rpx, bottom: 15.0.rpx),
-              color: Colors.white,
-              child: Row(
-                mainAxisAlignment: MainAxisAlignment.start,
-                crossAxisAlignment: CrossAxisAlignment.start,
-                children: [
-                  Image.asset(
-                    selected
-                        ? Assets.imagesIcRadioSelected
-                        : Assets.imagesIcRadio,
-                    height: 53.44.rpx,
-                    width: 53.44.rpx,
-                  ),
-                  SizedBox(
-                    width: 32.0.rpx,
-                  ),
-                  Expanded(child: Text(
-                      '$sn. $one',
-                      style: TextStyle(
-                          color:
-                          selected ? const Color(0xff00a0ff) : Colors.black),
-                      softWrap: true
-                  ))
-                  ,
-                ],
-              ))));
-      ascii++;
-    }
-
-    return Column(
-      mainAxisSize: MainAxisSize.min,
-      crossAxisAlignment: CrossAxisAlignment.start,
-      children: [
-        Text(extraInfo.question),
-        SizedBox(height: 39.0.rpx),
-        Row(
-          mainAxisAlignment: MainAxisAlignment.spaceBetween,
-          children: [
-            Expanded(
-                child: Column(
-                  mainAxisSize: MainAxisSize.min,
-                    crossAxisAlignment: CrossAxisAlignment.start,
-                    children: answers)),
-            bean(extraInfo.beanCount, 30.53.rpx),
-          ],
-        )
-      ],
-    );
-  }
-}
-
-
-
-class _Empty extends StatelessWidget {
-  @override
-  Widget build(BuildContext context) {
-    SizeFit.screenInit(context);
-    return const Scaffold(
-      floatingActionButton: FloatingActionButton(onPressed: _showDialog),
-    );
-  }
-}
-
-Future<void> _showDialog() async {
-  if (Get.isOverlaysOpen) {
-    Get.back();
-  }
-
-  final info = CPExtraInfoChoiceQuestion()
-    ..question = '计算题 23 + 8 - 6 = ?'
-    ..answers = ['22', '2312312312311', '242323', '21231231211111231235']
-    ..rightIndex = 3;
-
-  Get.dialog(
-    DialogCheckRich(
-      point: MControlPoint()
-        ..sn = '3'
-        ..areaId = 'A55'
-        ..checkAfterPrev = 2.1.minutes
-        ..extraInfo = info,
-      offAfter: 5.seconds,
-    ),
-  );
-}
-
-void main() async {
-  runApp(GetMaterialApp(theme: appThemeData(), home: _Empty()));
-}

+ 0 - 353
lib/view/ingame/dialog/dialog_check_rich2.dart

@@ -1,353 +0,0 @@
-import 'dart:async';
-import 'dart:convert';
-import 'package:assets_audio_player/assets_audio_player.dart';
-import 'package:flutter/material.dart';
-import 'package:get/get.dart';
-import 'package:trackoffical_app/generated/assets.dart';
-import 'package:trackoffical_app/logger.dart';
-import 'package:trackoffical_app/service/app.dart';
-import 'package:trackoffical_app/view/ingame/dialog/dialog_base.dart';
-import 'package:trackoffical_app/view/ingame/dialog/dialog_check_text.dart';
-import 'package:trackoffical_app/widget/app_net_image.dart';
-import '../../../model/cp_extra_info_choice_question.dart';
-import '../../../model/m_control_point.dart';
-import '../../../screen.dart';
-import '../../../styles/theme.dart';
-
-
-Future<void> showDialogCheckRich(
-    MControlPoint point,
-    Duration? offAfter,
-    ) async {
-  while(Get.isOverlaysOpen){
-    Get.back();
-  }
-
-  Get.dialog(DialogCheckRichSeq(
-    point,
-    offAfter,
-  ));
-}
-class DialogCheckRichSeq extends StatefulWidget{
-  const DialogCheckRichSeq(
-      this.point, this.offAfter, {super.key}
-      );
-
-  final MControlPoint point;
-  final Duration? offAfter;
-
-  @override
-  State<StatefulWidget> createState() {
-    return DialogCheckRichSeqState();
-  }
-}
-
-class DialogCheckRichSeqState extends State<DialogCheckRichSeq>{
-  var seq = 0;
-  var beanCount=0;
-  @override
-  void initState() {
-    super.initState();
-  }
-  @override
-  void dispose() {
-    super.dispose();
-
-  }
-  @override
-  Widget build(BuildContext context) {
-    final isShowOriginality = App.to.userProfile.gameSettingsShowOriginality.value;
-
-
-    if(seq==0){
-      return  DialogCheckText(
-        text: '打点成功',
-        color: const Color(0xffff870d),
-        beanCount: 1,
-        autoPlayAfter: 1.seconds,
-        closeAfterPlay: !isShowOriginality,
-        onStop: (){
-          if(mounted){
-            if (widget.point.extraInfo != null && isShowOriginality) {
-              setState(() {
-                seq = 1;
-              });
-            }
-          }
-        },
-      );
-    }
-    if(seq==1){
-      return DialogCheckRich(
-        point: widget.point,
-        offAfter: widget.offAfter,
-        onBeanCount: (c) {
-          beanCount = c;
-        },
-        onStop: (){
-          if(mounted){
-            setState(() {
-              seq = 2;
-            });
-          }
-        },
-      );
-    }
-    if(seq==2){
-      return  DialogCheckText(
-        text: '',
-        color: const Color(0xffff870d),
-        beanCount: beanCount,
-        autoPlayAfter: 1.seconds,
-      );
-    }
-
-    throw UnimplementedError();
-  }
-
-}
-
-
-
-class DialogCheckRich extends DialogBaseOffCount {
-  const DialogCheckRich({
-    super.key,
-    required this.point,
-    required super.offAfter,
-    required this.onBeanCount,
-    required this.onStop
-  }) : super(child: const SizedBox());
-
-  final Function(int c) onBeanCount;
-  final MControlPoint point;
-  final VoidCallback onStop;
-
-  @override
-  State<StatefulWidget> createState() {
-    return DialogCheckRichState();
-  }
-}
-
-class DialogCheckRichState extends DialogBaseOffCountState<DialogCheckRich> {
-  int? selectedIndex;
-  var isFinish = false;
-  final _audioPlayer = AssetsAudioPlayer.newPlayer();
-  var isAnswerOk = false;
-  @override
-  void onStop() {
-    widget.onStop();
-  }
-
-  void _setFinish() {
-    setState(() {
-      isFinish = true;
-    });
-    final src = isAnswerOk ? Assets.soundAnswerOk : Assets.soundAnswerFail;
-
-    _audioPlayer.open(
-      Audio(src),
-      autoStart: true,
-      showNotification: false,
-    );
-
-    1.seconds.delay().then((value) {
-      if (isActive && Get.isOverlaysOpen) {
-        // Get.back();
-        widget.onStop();
-      }
-    });
-  }
-
-  @override
-  void dispose() {
-    _audioPlayer.dispose();
-    super.dispose();
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    final style = (context.textTheme.titleLarge ?? const TextStyle())
-        .copyWith(color: const Color(0xff333333), fontSize: 41.98.rpx);
-
-    return DefaultTextStyle(
-        style: style,
-        child: Container(
-          width: context.width,
-          height: context.height,
-          color: const Color(0xB8000000),
-          alignment: Alignment.center,
-          child: Center(
-            child: Column(
-              mainAxisSize: MainAxisSize.min,
-              children: [
-                Container(
-                  decoration: BoxDecoration(
-                      color: const Color(0xE6FFFCF4),
-                      borderRadius: BorderRadius.only(
-                          bottomLeft: Radius.circular(2.25.wp),
-                          bottomRight: Radius.circular(2.25.wp))),
-                  padding: EdgeInsets.fromLTRB(
-                      4.5.wp,
-                      MediaQuery.of(context).padding.top + 4.5.wp,
-                      4.5.wp,
-                      11.4.wp),
-                  child: _wRich(),
-                ),
-                Obx(() => offCount(secondCount.value)),
-                const Spacer()
-              ],
-            ),
-          ),
-        ));
-  }
-
-  Widget _wTitle(CPExtraInfoChoiceQuestion extraInfo) {
-    const color = Color(0x80000000);
-
-    return Row(
-      crossAxisAlignment: CrossAxisAlignment.end,
-      children: [
-        Image.asset(Assets.imagesWarnFastThinker, width: 9.67.wp, color: color),
-        Text(
-          '快速思考',
-          style: TextStyle(color: color, fontSize: 4.58.wp),
-        ),
-        Text(
-          ' Think Fast',
-          style: TextStyle(color: const Color(0x33333333), fontSize: 3.56.wp),
-        ),
-        const Spacer(),
-        bean(extraInfo.beanCount, 3.31.wp)
-      ],
-    );
-  }
-
-  Widget _wRich() {
-    final extraInfo = widget.point.extraInfo!;
-    if (extraInfo is CPExtraInfoChoiceQuestion) {
-      return wExtraInfoChoiceQuestion(extraInfo);
-    } else {
-      throw UnimplementedError('wExtraInfo: $extraInfo 未实现');
-    }
-  }
-
-  Widget wExtraInfoChoiceQuestion(CPExtraInfoChoiceQuestion extraInfo) {
-    final children = <Widget>[];
-    var hasImage = false;
-    if (extraInfo.image != null) {
-      if (extraInfo.image!.md5.isNotEmpty) {
-        hasImage = true;
-        children.add(Container(
-            decoration: BoxDecoration(
-                border: Border.all(color: Colors.white, width: 0.78.wp),
-                borderRadius: BorderRadius.circular(1.78.wp)),
-            clipBehavior: Clip.hardEdge,
-            height: 40.97.wp,
-            child: ClipRRect(
-                borderRadius: BorderRadius.circular(1.78.wp),
-                child: AppNetImage(
-                  netImage: extraInfo.image!,
-                  fit: BoxFit.fitHeight,
-                ))));
-      }
-    }
-
-    children.addAll([
-      SizedBox(height: 2.29.wp),
-      ConstrainedBox(
-        constraints: hasImage
-            ? const BoxConstraints()
-            : BoxConstraints(minHeight: 26.0.wp),
-        child: Container(
-          width: double.infinity,
-          alignment: Alignment.centerLeft,
-          child: Text(extraInfo.question, style: TextStyle(fontSize: 4.58.wp)),
-        ),
-      ),
-      SizedBox(height: 2.29.wp),
-    ]);
-
-    var ascii = 65;
-
-    for (var i = 0; i < extraInfo.answers.length; i++) {
-      final one = extraInfo.answers[i];
-      final sn = const Utf8Codec().decode([ascii]);
-      final selected = i == selectedIndex;
-
-      children.add(GestureDetector(
-          onTap: () async {
-            if (selectedIndex == null) {
-              setState(() {
-                selectedIndex = i;
-              });
-
-              if (i == extraInfo.rightIndex) {
-                widget.onBeanCount(extraInfo.beanCount);
-              }
-              widget.point.userAnswerIndex = selectedIndex;
-              widget.point.isAnswerCorrect =
-                  selectedIndex == extraInfo.rightIndex;
-              isAnswerOk = widget.point.isAnswerCorrect;
-
-              _setFinish();
-            }
-          },
-          child: Container(
-              margin: EdgeInsets.only(top: 2.8.wp, bottom: 2.8.wp),
-              padding: EdgeInsets.only(left: 4.8.wp),
-              alignment: Alignment.centerLeft,
-              decoration: BoxDecoration(
-                  color: Color(selected ? 0xff00a0ff : 0xff017dc7),
-                  borderRadius: BorderRadius.circular(1.78.wp)),
-              height: 13.49.wp,
-              width: double.infinity,
-              child: Text('$sn. $one',
-                  maxLines: 1,
-                  overflow: TextOverflow.ellipsis,
-                  style: const TextStyle(color: Colors.white)))));
-      ascii++;
-    }
-
-    return Column(
-      mainAxisSize: MainAxisSize.min,
-      children: [
-        _wTitle(extraInfo),
-        const Divider(),
-        Padding(
-            padding: EdgeInsets.only(left: 8.52.wp, right: 8.52.wp, top: 7.26),
-            child: Column(
-              mainAxisSize: MainAxisSize.min,
-              children: children,
-            ))
-      ],
-    );
-  }
-}
-
-class _Empty extends StatelessWidget {
-  @override
-  Widget build(BuildContext context) {
-    SizeFit.screenInit(context);
-
-    final info = CPExtraInfoChoiceQuestion()
-      ..question = '计算题 23 + 8 - 6 = ?'
-      ..answers = ['22', '2312312312311', '242323', '21231231211111231235']
-      ..rightIndex = 3;
-
-    return Scaffold(
-      floatingActionButton: FloatingActionButton(
-          onPressed: () => showDialogCheckRich(
-                MControlPoint()
-                  ..sn = '3'
-                  ..areaId = 'A55'
-                  ..checkAfterPrev = 2.1.minutes
-                  ..extraInfo = info,
-                3.seconds,
-              )),
-    );
-  }
-}
-
-void main() async {
-  runApp(GetMaterialApp(theme: appThemeData(), home: _Empty()));
-}

+ 0 - 199
lib/view/ingame/dialog/dialog_check_text.dart

@@ -1,199 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:get/get.dart';
-import 'package:trackoffical_app/logger.dart';
-import 'package:trackoffical_app/screen.dart';
-
-import '../../../styles/theme.dart';
-import 'dialog_base.dart';
-
-class DialogCheckText extends StatefulWidget {
-  const DialogCheckText({
-    super.key,
-    required
-    this.text,
-    required this.color,
-    this.autoPlayAfter,
-    this.closeAfterPlay=true,
-    this.beanCount,
-    this.onStop,
-  });
-
-  final String text;
-  final Color color;
-  final Duration? autoPlayAfter;
-  final bool closeAfterPlay;
-  final int? beanCount;
-  final VoidCallback? onStop;
-
-  @override
-  State<StatefulWidget> createState() {
-    return DialogCheckTextState();
-  }
-}
-
-class DialogCheckTextState extends State<DialogCheckText>
-    with SingleTickerProviderStateMixin{
-
-  AnimationController? _animationController;
-  Animation<double?>? _animation;
-  static const milliseconds = 400;
-  var willClose =false;
-  var isActive=true;
-
-  @override
-  void initState() {
-    super.initState();
-
-    if(widget.autoPlayAfter!= null){
-      widget.autoPlayAfter!.delay(onClick);
-    }
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    final maxFontSize = 28.5.wp;
-    var alpha = 255;
-    var fontSize = 11.2.wp;
-    final v = _animation?.value;
-    var beanAlpha = 1.0;
-    var beanSize = 9.92.wp;
-    final maxBeanSize = 18.0.wp;
-    if(v!= null){
-      alpha -= (v *255).round();
-      var d = (maxFontSize - fontSize);
-      fontSize += d * v;
-      beanAlpha -= v;
-
-      d = (maxBeanSize - beanSize);
-      beanSize += d * v;
-    }
-
-
-
-    final children = <Widget>[];
-    
-    if(widget.text.isNotEmpty){
-      children.add(
-        Container(
-          height: 41.22.wp,
-          alignment: Alignment.center,
-          child: Text(
-            widget.text,
-            style: context.textTheme.titleLarge?.copyWith(
-                color: widget.color.withAlpha( alpha),
-                fontSize: fontSize,
-                fontWeight: FontWeight.w700),
-            maxLines: 1,
-          )
-        )
-      );
-    }
-    
-    final beanCount = widget.beanCount;
-    
-    if(beanCount!= null){
-      if(widget.text.isNotEmpty){
-        children.add(SizedBox(height: 7.64.wp,));
-      }
-      
-      children.add(Container(
-        height: 45.0.wp,
-        alignment: Alignment.center,
-        child: Opacity(
-          opacity: beanAlpha,
-          child: bean(beanCount, beanSize),
-        ) ,
-      ) );
-    }
-    
-    return GestureDetector(
-      onTap: onClick,
-      child: Container(
-        width: context.width,
-        height: context.height,
-        color: const Color(0xB8000000),
-        alignment: Alignment.center,
-        child: DefaultTextStyle(
-          style: context.textTheme.titleLarge??const TextStyle(),
-          child: Column(
-            mainAxisSize: MainAxisSize.min,
-            children: children,
-          )
-        )
-      ),
-    ) ;
-  }
-
-
-  void onClick(){
-    if(willClose){
-      return;
-    }
-    willClose=true;
-    doClick();
-  }
-
-  Future<void> doClick()async{
-    if(!isActive){
-      return;
-    }
-
-    _animationController = AnimationController(
-      vsync: this,
-      duration: const Duration(milliseconds: milliseconds),
-      reverseDuration: const Duration(milliseconds: milliseconds),
-    )..repeat(reverse: false);
-    _animation =Tween<double>(begin: 0, end: 1)
-        .animate(_animationController!)
-      ..addListener(() {
-        setState(() {
-          // The state that has changed here is the animation object’s value.
-        });
-      });
-
-    await Future.delayed(milliseconds.milliseconds);
-    _animationController?.dispose();
-    _animationController=null;
-
-    widget.onStop?.call();
-    if(mounted&&Get.isOverlaysOpen&&widget.closeAfterPlay){
-      debug('${widget.runtimeType} back');
-      Get.back();
-    }
-  }
-
-  @override
-  void dispose() {
-    super.dispose();
-    isActive=false;
-    _animationController?.dispose();
-    _animationController=null;
-  }
-
-}
-
-
-class _Empty extends StatelessWidget {
-  @override
-  Widget build(BuildContext context) {
-    SizeFit.screenInit(context);
-    return const Scaffold(
-      floatingActionButton: FloatingActionButton(onPressed: _showDialog),
-    );
-  }
-}
-
-Future<void> _showDialog() async {
-  if (Get.isOverlaysOpen) {
-    Get.back();
-  }
-  Get.dialog(DialogCheckText(
-    text: '打点错误',
-    color: Colors.red,
-    beanCount: 1,
-  ));
-}
-
-void main() async {
-  runApp(GetMaterialApp(theme: appThemeData(), home: _Empty()));
-}

+ 0 - 48
lib/view/ingame/dialog/dialog_confirm_finish.dart

@@ -1,48 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:get/get.dart';
-import 'package:trackoffical_app/screen.dart';
-import 'package:trackoffical_app/view/ingame/dialog/dialog_base.dart';
-
-import '../../../styles/theme.dart';
-import 'dialog_button.dart';
-
-Future<bool> dialogAskConfirmFinish() async {
-  final r = await Get.dialog(
-    dialogTitle(
-        '已打结束点',
-        Colors.red,
-        Column(
-          children: [
-            const Text('10秒后自动结束比赛'),
-            SizedBox(height: 76.3.rpx),
-            dialogButton('取消', () {
-              Get.back(result: false);
-            })
-          ],
-        ),
-        offAfter: 10.seconds),
-  );
-
-  return r != false;
-}
-
-
-
-class _Empty extends StatelessWidget {
-  @override
-  Widget build(BuildContext context) {
-    SizeFit.screenInit(context);
-    return Scaffold(
-      floatingActionButton: FloatingActionButton(onPressed: (){
-        dialogAskConfirmFinish().then((value) =>
-            print('result: $value')
-        );
-      }),
-    );
-  }
-}
-
-
-void main() async {
-  runApp(GetMaterialApp(theme: appThemeData(), home: _Empty()));
-}

+ 0 - 61
lib/view/ingame/dialog/dialog_cp_order_err.dart

@@ -1,61 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:get/get.dart';
-import 'package:trackoffical_app/model/m_control_point.dart';
-import 'package:trackoffical_app/screen.dart';
-import 'package:trackoffical_app/view/ingame/dialog/dialog_base.dart';
-import 'package:trackoffical_app/view/ingame/utils.dart';
-
-import '../../../styles/theme.dart';
-import 'dialog_button.dart';
-
-void dialogCPOrderErr(MControlPoint next) {
-  var text = '请前往${next.snString}点';
-  if(next.areaId.isNotEmpty){
-    text += ' (${next.areaId})';
-  }
-
-  Get.dialog(
-    dialogTitle(
-        '打点错误',
-        Colors.red,
-        Column(
-          children: [
-            Row(
-              mainAxisSize: MainAxisSize.min,
-              children: [
-                Text(text),
-                SizedBox(width: 40.0.rpx),
-                next.icon(height: 66.79.rpx),
-              ],
-            )
-          ],
-        ),
-        offAfter: 3.seconds),
-  );
-}
-
-
-
-class _Empty extends StatelessWidget {
-  @override
-  Widget build(BuildContext context) {
-    SizeFit.screenInit(context);
-
-    final cp = MControlPoint()
-      ..areaId='A51'
-      ..sn='1'
-      ..isStart=true
-    ;
-
-    return Scaffold(
-      floatingActionButton: FloatingActionButton(onPressed: (){
-        dialogCPOrderErr(cp);
-      }),
-    );
-  }
-}
-
-
-void main() async {
-  runApp(GetMaterialApp(theme: appThemeData(), home: _Empty()));
-}

+ 0 - 170
lib/view/ingame/dialog/dialog_finish_result.dart

@@ -1,170 +0,0 @@
-import 'package:assets_audio_player/assets_audio_player.dart';
-import 'package:flutter/material.dart';
-import 'package:get/get.dart';
-import 'package:trackoffical_app/generated/assets.dart';
-import 'package:trackoffical_app/route.dart';
-import 'package:trackoffical_app/screen.dart';
-import 'package:trackoffical_app/utils.dart';
-import 'package:trackoffical_app/view/ingame/dialog/dialog_base.dart';
-import 'package:trackoffical_app/pb.dart' as pb;
-import '../../../styles/theme.dart';
-import 'dialog_button.dart';
-
-Widget _elem(String iconSrc, String title, String value, String unit) {
-  final style = TextStyle(
-      fontSize: 45.8.rpx,
-      fontWeight: FontWeight.w500,
-      color: const Color(0xff333333));
-
-  return Padding(
-      padding: EdgeInsets.only(top: 21.0.rpx, bottom: 21.0.rpx),
-      child: Row(
-        children: [
-          Image.asset(iconSrc, height: 45.8.rpx),
-          SizedBox(width: 9.5.rpx),
-          Expanded(
-              child: Text(
-            title,
-            style: style.copyWith(fontSize: 34.35.rpx),
-          )),
-          RichText(
-              text: TextSpan(text: value, style: style, children: [
-            TextSpan(
-              text: unit,
-              style: style.copyWith(
-                  fontSize: 19.1.rpx, color: const Color(0xff818181)),
-            ),
-          ]))
-        ],
-      ));
-}
-
-
-void _goNext(){
-  Get.offAllNamed(RouteName.home);
-}
-enum _State{
-  success,
-  ok,
-  fail
-}
-void dialogFinishResult(pb.GameSettlement data) {
-  var state = _State.success;
-  var title = '恭喜!挑战成功';
-  var titleColor = const Color(0xFFFF870D);
-  Color? buttonColor = const Color(0xFF017DC7);
-  var soundSrc = Assets.soundFinishSuccess;
-  if(!data.isSuccess){
-    state = _State.ok;
-  }
-  if(!data.isComplete){
-    state=_State.fail;
-  }
-  switch(state){
-    case _State.ok:
-      title = '挑战完成';
-      titleColor = Colors.red;
-      buttonColor = null;
-      soundSrc = Assets.soundFinishOk;
-      break;
-    case _State.fail:
-      title = '挑战失败';
-      titleColor = Colors.red;
-      buttonColor = null;
-      soundSrc = Assets.soundFinishFail;
-      break;
-    default:
-  }
-
-  AssetsAudioPlayer.newPlayer().open(
-      Audio(soundSrc),
-      autoStart: true,
-      showNotification: false);
-
-  final minutes = data.duration.toDuration().inSeconds.toDouble() /
-      Duration.secondsPerMinute;
-  final distanceKm = data.distance.toDouble() / 1000;
-  final kcal = data.calorie.toDouble() / 1000;
-
-  Get.dialog(
-      WillPopScope(
-          onWillPop: () async{
-            _goNext();
-            return false;
-          },
-          child: dialogTitle(
-              title,
-              titleColor,
-              Column(
-                crossAxisAlignment: CrossAxisAlignment.center,
-                children: [
-                  Card(
-                    child: Padding(
-                        padding: EdgeInsets.fromLTRB(
-                          41.1.rpx,
-                          10.1.rpx,
-                          41.1.rpx,
-                          10.1.rpx,
-                        ),
-                        child: Column(
-                          children: [
-                            _elem(Assets.imagesIcFinishTime, '总用时',
-                                minutes.toStringAsFixed(1), ' min '),
-                            _elem(Assets.imagesIcFinishTime, '总里程',
-                                distanceKm.toStringAsFixed(1), ' km  '),
-                            _elem(Assets.imagesIcFinishTime, '消耗卡路里',
-                                kcal.toStringAsFixed(1), ' kcal'),
-                            _elem(Assets.imagesIcFinishTime, '脑力值',
-                                data.answerHistory.accuracy.toString(), ' %   '),
-                          ],
-                        )),
-                  ),
-                  SizedBox(height: 30.0.rpx),
-                  Row(
-                    mainAxisSize: MainAxisSize.min,
-                    children: [
-                      Image.asset(Assets.imagesIcBean, height: 103.9.rpx),
-                      Column(
-                        mainAxisSize: MainAxisSize.min,
-                        children: [
-                          Text('X ${data.sysPoint}',
-                              style: TextStyle(fontSize: 53.44.rpx)),
-                          Text('共获得${data.sysPoint}个百味豆',
-                              style: TextStyle(
-                                  fontSize: 22.9.rpx,
-                                  color: const Color(0xFFaaaaaa))),
-                        ],
-                      )
-                    ],
-                  ),
-                  SizedBox(height: 30.0.rpx),
-                  dialogButton('确定', _goNext, color: buttonColor),
-                  SizedBox(height: 30.0.rpx),
-                  Text(
-                    '提示:可以在“成就”中查看详细数据',
-                    style: TextStyle(color: Colors.red, fontSize: 28.63.rpx),
-                  )
-                ],
-              )),),
-
-      barrierDismissible: false
-  );
-}
-
-class _Empty extends StatelessWidget {
-  @override
-  Widget build(BuildContext context) {
-    SizeFit.screenInit(context);
-    final data = pb.GameSettlement();
-
-    return Scaffold(
-      floatingActionButton: FloatingActionButton(onPressed: () {
-        dialogFinishResult(data);
-      }),
-    );
-  }
-}
-
-void main() async {
-  runApp(GetMaterialApp(theme: appThemeData(), home: _Empty()));
-}

+ 0 - 108
lib/view/ingame/dialog/dialog_start_warn.dart

@@ -1,108 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:get/get.dart';
-import 'package:trackoffical_app/generated/assets.dart';
-import 'package:trackoffical_app/screen.dart';
-import 'package:trackoffical_app/service/app.dart';
-import 'package:trackoffical_app/service/mock.dart';
-import 'package:trackoffical_app/view/ingame/dialog/dialog_base.dart';
-import '../../../styles/theme.dart';
-import 'dialog_button.dart';
-
-Widget _elem(String iconSrc, String title) {
-  final style = TextStyle(
-      fontSize: 45.8.rpx,
-      fontWeight: FontWeight.w500,
-      color: const Color(0xff333333));
-
-  return Container(
-      decoration: BoxDecoration(
-          color: Colors.white, borderRadius: BorderRadius.circular(1.2.wp)),
-      padding: EdgeInsets.only(left: 2.55.wp, top: 1.78.wp, bottom: 1.78.wp),
-      margin: EdgeInsets.only(bottom: 3.81.wp),
-      child: Row(
-        children: [
-          Image.asset(iconSrc, height: 9.16.wp),
-          SizedBox(width: 9.5.rpx),
-          Expanded(
-              child: Text(
-            title,
-            style: style.copyWith(fontSize: 34.35.rpx),
-          )),
-        ],
-      ));
-}
-
-class DialogStartWarn extends StatefulWidget {
-  const DialogStartWarn({super.key});
-
-  @override
-  State<StatefulWidget> createState() {
-    return DialogStartWarnState();
-  }
-}
-
-class DialogStartWarnState extends State<DialogStartWarn> {
-  @override
-  Widget build(BuildContext context) {
-    const title = '为了获得更好的体验';
-    const titleColor = Color(0xFFce0000);
-
-    return dialogTitle(
-        title,
-        titleColor,
-        Column(children: [
-          _elem(Assets.imagesIcWarnSound, '调大手机音量'),
-          _elem(Assets.imagesIcWarnVibrate, '开启手机震动'),
-          _elem(Assets.imagesIcWarnBrightness, '强光下将屏幕调至最亮'),
-          GestureDetector(
-              onTap: () {
-                setState(() {
-                  App.to.userProfile.isEnableInGameStartWarn.val =
-                      !App.to.userProfile.isEnableInGameStartWarn.val;
-                });
-              },
-              child: Row(children: [
-                Container(
-                    width: 10.36.wp,
-                    height: 10.36.wp,
-                    padding: EdgeInsets.all(2.0.wp),
-                    child: Stack(
-                      children: [
-                        Image.asset(Assets.imagesIcSelectRect),
-                        !App.to.userProfile.isEnableInGameStartWarn.val
-                            ? Image.asset(Assets.imagesIcSelectRectSelected)
-                            : const SizedBox()
-                      ],
-                    )),
-                const Text('下次不再提醒'),
-              ])),
-          SizedBox(height: 4.0.wp),
-          dialogButton('确定', () {
-            Get.back();
-          })
-        ]));
-  }
-}
-
-Future<void> dialogStartWarn() async{
-  await Get.dialog(const DialogStartWarn(), barrierDismissible: true);
-  return;
-}
-
-class _Empty extends StatelessWidget {
-  @override
-  Widget build(BuildContext context) {
-    SizeFit.screenInit(context);
-
-    return Scaffold(
-      floatingActionButton: FloatingActionButton(onPressed: () {
-        dialogStartWarn();
-      }),
-    );
-  }
-}
-
-void main() async {
-  Mock.initServices();
-  runApp(GetMaterialApp(theme: appThemeData(), home: _Empty()));
-}

+ 0 - 121
lib/view/ingame/dialog_checked.dart

@@ -1,121 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter_svg/svg.dart';
-import 'package:get/get.dart';
-import '../../model.dart';
-import '../../widget/app_net_image.dart';
-import '../../styles/color_schemes.g.dart';
-
-class DialogChecked extends StatelessWidget {
-  final VoidCallback? onConfirm;
-  final String title;
-  final String sn;
-  final MNetImage? image;
-  final String content;
-  final bool isOk;
-
-  const DialogChecked({
-    super.key,
-    required this.title,
-    required this.sn,
-    required this.isOk,
-    this.onConfirm,
-    this.image,
-    this.content = '',
-  });
-
-  @override
-  Widget build(BuildContext context) {
-    return Padding(
-        padding: const EdgeInsets.fromLTRB(50, 80, 50, 80),
-        child: Column(
-          children: [
-            Expanded(
-                child: Stack(
-              children: [
-                SvgPicture.asset(
-                  'assets/images/bk_check_point.svg',
-                  height: double.infinity,
-                  width: double.infinity,
-                  fit: BoxFit.fill,
-                ),
-                Padding(
-                    padding: const EdgeInsets.all(44),
-                    child: Column(
-                      children: [
-                        Text(
-                          title,
-                          style: context.textTheme.headlineLarge,
-                        ),
-                        Text(sn, style: context.textTheme.titleLarge,),
-                        isOk?const SizedBox(width: 0, height: 0)
-                            :Text('顺序错误,请去正确的检查点',
-                            style: context.textTheme.bodyLarge?.copyWith(
-                                color: context.theme.colorScheme.error)),
-                        const Divider(),
-                        const SizedBox(height: 12),
-                        ConstrainedBox(
-                          constraints: const BoxConstraints(
-                            maxHeight: 120,
-                          ),
-                          child: AppNetImage(
-                              netImage: image ?? MNetImage(),
-                              fit: BoxFit.contain),
-                        ),
-                        const SizedBox(height: 12),
-                        SizedBox(
-                          width: double.infinity,
-                          child: Text(
-                            content,
-                            style: context.textTheme.bodyLarge,
-                          ),
-                        ),
-                      ],
-                    )),
-                isOk?
-                Positioned(
-                  right: 30,
-                  bottom: 60,
-                  child: Transform.rotate(
-                    angle: -0.3,
-                    child: Image.asset(
-                      'assets/images/ic_checked.png',
-                      width: 100,
-                      height: 40,
-                      fit: BoxFit.fill,
-                    ),
-                  ),
-                ):const SizedBox(width: 0, height: 0)
-              ],
-            )),
-            const SizedBox(height: 18),
-            ElevatedButton(onPressed: onConfirm, child: const Text('确定'))
-          ],
-        ));
-  }
-}
-
-class _Empty extends StatelessWidget {
-  @override
-  Widget build(BuildContext context) {
-    _showDialog();
-
-    return const Scaffold();
-  }
-}
-
-Future<void> _showDialog() async {
-  await Future.delayed(2.seconds);
-
-  Get.dialog(const DialogChecked(
-    title: '点位: 231',
-    sn: "A123",
-    isOk: true,
-    content: '一些内容',
-  ));
-}
-
-void main() async {
-  runApp(GetMaterialApp(
-      theme: ThemeData(useMaterial3: true, colorScheme: lightColorScheme),
-      home: _Empty()));
-}

+ 0 - 304
lib/view/ingame/dialog_checked2.dart

@@ -1,304 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:get/get.dart';
-import 'package:trackoffical_app/model/m_control_point.dart';
-import 'package:trackoffical_app/styles/theme.dart';
-
-const horizontalEdge = 20.0;
-const cardHeight = 225.4;
-
-double _getCardTop(BuildContext context) {
-  return (context.height - cardHeight) / 2.7;
-}
-
-class DialogChecked2 extends StatelessWidget {
-  final VoidCallback? onConfirm;
-  final MControlPoint currentPoint;
-  final MControlPoint? nextPoint;
-  final mainColor = const Color(0xffff8000);
-
-  const DialogChecked2({
-    super.key,
-    this.onConfirm,
-    required this.currentPoint,
-    this.nextPoint,
-  });
-
-  @override
-  Widget build(BuildContext context) {
-    final backColor = currentPoint.isSuccess
-        ? const Color(0xff0aad81)
-        : const Color(0xffff8000);
-    final bordColor = currentPoint.isSuccess
-        ? const Color(0xff64cbb0)
-        : const Color(0xffffd6d6);
-
-    var text = '';
-
-    Widget bean = const SizedBox();
-
-    final cardTop = _getCardTop(context);
-
-    if (currentPoint.isSuccess) {
-      if (currentPoint.sn == MControlPoint.snStart) {
-        text = '游戏开始';
-      } else if (currentPoint.sn == MControlPoint.snFinish) {
-        text = '恭喜完赛';
-      } else {
-        text = '打卡成功';
-        bean = Positioned(
-            top: cardHeight + 40,
-            child: Column(
-              mainAxisSize: MainAxisSize.min,
-              children: [
-                Row(
-                  mainAxisSize: MainAxisSize.min,
-                  children: [
-                    Image.asset('assets/images/ic_bean.png',
-                        height: 52, fit: BoxFit.fitHeight),
-                    Text(' X 1',
-                        style: context.textTheme.titleLarge
-                            ?.copyWith(color: Colors.white, fontSize: 24))
-                  ],
-                ),
-                const SizedBox(height: 17),
-                Text('获得百味豆1个哦',
-                    style: context.textTheme.titleLarge?.copyWith(
-                        color: const Color(0xff9d9d9d), fontSize: 15))
-              ],
-            ));
-      }
-    } else {
-      text = '顺序错误';
-    }
-
-    return Padding(
-        padding:
-            EdgeInsets.fromLTRB(horizontalEdge, cardTop, horizontalEdge, 80),
-        child: GestureDetector(
-            onTap: () => Get.back(),
-            child: SizedBox(
-                width: double.infinity,
-                height: double.infinity,
-                child: Stack(
-                  alignment: Alignment.topCenter,
-                  children: [
-                    CustomPaint(
-                      painter: _BackGround(color: backColor),
-                      child: Container(
-                        margin: const EdgeInsets.all(10),
-                        width: 276.5,
-                        height: cardHeight,
-                        decoration: BoxDecoration(
-                            border: Border.all(color: bordColor, width: 2),
-                            borderRadius: BorderRadius.circular(7.62)),
-                        child: Column(
-                          children: [
-                            Expanded(
-                                child: Row(
-                              children: [
-                                Expanded(child: Center(child: _getSn(context))),
-                                VerticalDivider(width: 2, color: bordColor),
-                                Expanded(
-                                    child: Column(
-                                  mainAxisSize: MainAxisSize.min,
-                                  children: [
-                                    Text('检查点',
-                                        style: context.textTheme.bodyLarge
-                                            ?.copyWith(
-                                                color: Colors.white,
-                                                fontSize: 33.76)),
-                                    Container(
-                                      height: 48,
-                                      width: 102.36,
-                                      alignment: Alignment.center,
-                                      decoration: BoxDecoration(
-                                          color: Colors.white,
-                                          borderRadius:
-                                              BorderRadius.circular(3.27)),
-                                      child: Text(currentPoint.areaId,
-                                          style: context.textTheme.bodyLarge
-                                              ?.copyWith(
-                                                  height: 0.77,
-                                                  color: backColor,
-                                                  fontSize: 49,
-                                                  fontWeight: FontWeight.w600)),
-                                    )
-                                  ],
-                                )),
-                              ],
-                            )),
-                            Divider(height: 2, color: bordColor),
-                            Expanded(
-                                child: Center(
-                                    child: Text(text,
-                                        style: context.textTheme.titleLarge
-                                            ?.copyWith(
-                                                color: Colors.white,
-                                                fontSize: 49,
-                                                fontWeight: FontWeight.w700))))
-                          ],
-                        ),
-                      ),
-                    ),
-                    bean
-                    // Positioned(top: 20, left: 0, child: _okMsg(context)),
-                    // Positioned(top: 120, left: 0, child: _topCard(context)),
-                    // Positioned(top: 320, left: 0, child: _memo(context)),
-                    // Positioned(top: 400, left: 0, child: _closeBtn(context)),
-                  ],
-                ))));
-  }
-
-  Widget _getSn(BuildContext context) {
-    var src = '';
-
-    if (currentPoint.isSuccess) {
-      if (currentPoint.sn == MControlPoint.snStart) {
-        src = 'ic_checked_start.png';
-      } else if (currentPoint.sn == MControlPoint.snFinish) {
-        src = 'ic_checked_finish.png';
-      } else {
-        return Text("${currentPoint.sn}号",
-            style: context.textTheme.titleLarge?.copyWith(
-                color: Colors.white,
-                fontSize: 54.44,
-                fontWeight: FontWeight.w500));
-      }
-    } else {
-      src = 'ic_checked_fail.png';
-    }
-
-    return Image.asset('assets/images/$src', height: 60, fit: BoxFit.fitHeight);
-  }
-}
-
-class _BackGround extends CustomPainter {
-  final Color color;
-
-  _BackGround({required this.color});
-
-  @override
-  void paint(Canvas canvas, Size size) {
-    var paint = Paint()
-      ..color = color
-      ..maskFilter = const MaskFilter.blur(BlurStyle.solid, 12);
-
-    canvas.drawRRect(
-        RRect.fromRectAndRadius(Rect.fromLTWH(0, 0, size.width, size.height),
-            const Radius.circular(12)),
-        paint);
-  }
-
-  @override
-  bool shouldRepaint(covariant CustomPainter oldDelegate) {
-    return this != oldDelegate;
-  }
-}
-
-class DialogGiveUp extends StatelessWidget {
-  final VoidCallback onConfirm;
-  final VoidCallback onCancel;
-
-  const DialogGiveUp(
-      {super.key, required this.onConfirm, required this.onCancel});
-
-  @override
-  Widget build(BuildContext context) {
-    return Padding(
-        padding: EdgeInsets.fromLTRB(
-            horizontalEdge, _getCardTop(context), horizontalEdge, 80),
-        child: Stack(
-          alignment: Alignment.topCenter,
-          children: [
-            CustomPaint(
-                painter: _BackGround(color: const Color(0xffff0000)),
-                child: Container(
-                    margin: const EdgeInsets.all(10),
-                    width: 276.5,
-                    height: cardHeight,
-                    alignment: Alignment.center,
-                    decoration: BoxDecoration(
-                        border: Border.all(
-                            color: const Color(0xffffd6d6), width: 2),
-                        borderRadius: BorderRadius.circular(7.62)),
-                    child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.center,
-                      mainAxisSize: MainAxisSize.min,
-                      children: [
-                        Text('退出比赛',
-                            style: context.textTheme.titleLarge?.copyWith(
-                                color: Colors.white,
-                                fontSize: 35.93,
-                                fontWeight: FontWeight.w700)),
-                        const SizedBox(height: 19),
-                        Text(
-                          '是否强制结束?',
-                          style: context.textTheme.titleLarge
-                              ?.copyWith(color: Colors.white, fontSize: 19.6),
-                        ),
-                        const SizedBox(height: 35),
-                        Row(
-                          mainAxisSize: MainAxisSize.min,
-                          children: [
-                            SizedBox(
-                                width: 100,
-                                height: 41,
-                                child: OutlinedButton(
-                                    onPressed: onCancel,
-                                  style: OutlinedButton.styleFrom(side: BorderSide(width: 1, color: Colors.white)),
-                                    child: const Text(
-                                      '否',
-                                      style: TextStyle(height: 0.1,
-                                          color: Colors.white, fontSize: 26),
-                                    ))),
-                            const SizedBox(width: 23),
-                            SizedBox(
-                                width: 100,
-                                height: 41,
-                                child: FilledButton(
-                                    onPressed: onConfirm,
-                                    style: FilledButton.styleFrom(backgroundColor: Colors.white),
-                                    child: const Text('是',
-                                        style: TextStyle(
-                                          height: 0.1,
-                                            color: Color(0xffff0000),
-                                            fontSize: 26))))
-                          ],
-                        )
-                      ],
-                    )))
-          ],
-        ));
-  }
-}
-
-class _Empty extends StatelessWidget {
-  @override
-  Widget build(BuildContext context) {
-    _showDialog();
-
-    return const Scaffold();
-  }
-}
-
-Future<void> _showDialog() async {
-  await Future.delayed(2.seconds);
-  if (Get.isOverlaysOpen) {
-    Get.back();
-  }
-
-  Get.dialog(DialogChecked2(
-    onConfirm: () {},
-    currentPoint: MControlPoint(
-        // sn: ControlPointText.snFinish,
-        sn: "12",
-        areaId: 'A51',
-        isSuccess: true),
-    nextPoint: MControlPoint(
-        sn: MControlPoint.snFinish, areaId: 'A52', isSuccess: true),
-  ));
-}
-
-void main() async {
-  runApp(GetMaterialApp(theme: appThemeData(), home: _Empty()));
-}

+ 0 - 352
lib/view/ingame/game_compass/game_compass_base.dart

@@ -1,352 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:get/get.dart';
-import 'package:trackoffical_app/screen.dart';
-import 'package:trackoffical_app/utils.dart';
-import 'package:vector_math/vector_math_64.dart' as vec;
-import '../../../widget/compass2.dart';
-import '../game_std/utils.dart';
-import '../widget_ruler2.dart';
-import 'game_compass_top4_data.dart';
-export 'game_compass_top4_data.dart';
-export 'game_compass_button.dart';
-export 'package:flutter/material.dart';
-
-class GameCompassController{
-  final heartRatePercent = 0.0.obs;
-  final isNoMapRulerScaleMode=false.obs;
-  final duration = 0.seconds.obs;
-  final compassRadians= 0.0.obs;
-  final nextPointRadians= 0.0.obs;
-  final heartRate = 0.obs;
-  final stepCount=0.obs;
-  final kCal= 0.0.obs;
-  final ck= 0.0.obs;
-  final ei= 0.0.obs;
-
-  /// 地图比例尺 1:[userSetMapScale]
-  final Rx<double?> userSetMapScale = Rx(null);
-}
-
-
-class GameCompassBase extends StatelessWidget{
-  const GameCompassBase({
-    super.key,
-    required this.controller,
-    required this.top4data,
-    required this.topButtons,
-    required this.process,
-    this.compassDiameter=230,
-    required this.isShowNextPointer,
-    required this.isEnableRuler, required this.bottomCenterButton,
-  });
-
-  static const _hPadding = 60.0;
-  final GameCompassController controller;
-  final List<GameCompassTop4Data> top4data;
-  final List<Widget> topButtons;
-  final Widget? process;
-  final double compassDiameter;
-  final bool isShowNextPointer;
-  final bool isEnableRuler;
-  final Widget bottomCenterButton;
-
-  @override
-  Widget build(BuildContext context) {
-    return Scaffold(
-        body: DefaultTextStyle(
-          style: const TextStyle(color: Colors.white),
-          child: Stack(
-            children: [
-              Obx(() => Container(
-                decoration: BoxDecoration(
-                    color: controller.heartRatePercent.value.round().toHRPColor()),
-                width: context.width,
-                height: context.height,
-              )),
-              Obx(() => !controller.isNoMapRulerScaleMode.value
-                  ? const Ruler2(isScaleMode: false)
-                  : const SizedBox()),
-              Container(
-                  padding: EdgeInsets.only(
-                      top: context.mediaQueryPadding.top,
-                      left: _hPadding,
-                      right: _hPadding),
-                  width: context.width,
-                  child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.center,
-                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                      children: [
-                        const SizedBox(height: 20),
-                        _topButtonBar(),
-                        _wDuration(),
-                        _process(),
-                        _topElemHub(),
-                        _compass(),
-                        _heartRate(),
-                        _sports(),
-                        _bottomBar(),
-                      ])),
-              Obx(() => controller.isNoMapRulerScaleMode.value && isEnableRuler
-                  ? Ruler2(
-                  isScaleMode: true,
-                  onReturn: () =>
-                  controller.isNoMapRulerScaleMode.value = false,
-                  mapScale: controller.userSetMapScale.value)
-                  : const SizedBox(height: 0))
-            ],
-          ),
-        ));
-  }
-
-  Widget _topButtonBar() {
-    return Row(
-      mainAxisAlignment: MainAxisAlignment.spaceBetween,
-      children: topButtons,
-    );
-  }
-
-  Widget _wDuration() {
-    return Obx(() => Text(controller.duration.value.toAppString(),
-        maxLines: 1,
-        style: const TextStyle(
-          fontSize: 29,
-          fontFamily: 'sa-digital-number',
-        )));
-  }
-
-  Widget _process() {
-    final w = process;
-    return w!= null?DefaultTextStyle(style: const TextStyle(
-      fontSize: 32,
-    ), child: w): const SizedBox();
-  }
-
-  Widget _topElemHub() {
-    final rows = <Widget>[];
-    final titles = <Widget>[];
-    final divider = SizedBox(width: 2.78.wp);
-
-    rows.add(Row(
-      children: [
-        top4data[0],
-        divider,
-        top4data[1],
-      ],
-    ));
-
-    titles.addAll([
-      Positioned(
-          left: 0,
-          top: 0,
-          child: _getSmallTitle(top4data[0].title)
-      ),
-      Positioned(
-          right: 0,
-          top: 0,
-          child: _getSmallTitle(top4data[1].title)
-      ),
-    ]);
-
-    if(top4data.length==4){
-      rows.add(SizedBox(height: 2.78.wp));
-      rows.add(Row(
-        children: [
-          top4data[2],
-          divider,
-          top4data[3],
-        ],
-      ));
-
-      titles.addAll([
-        Positioned(
-            left: 0,
-            bottom: 0,
-            child: _getSmallTitle(top4data[2].title)
-        ),
-        Positioned(
-            right: 0,
-            bottom: 0,
-            child: _getSmallTitle(top4data[3].title)
-        ),
-      ]);
-    }
-
-    final stacks = <Widget>[
-      Column(
-        children: rows,
-      )
-    ];
-
-    stacks.addAll(titles);
-
-    return Stack(
-      children: stacks,
-    ) ;
-  }
-
-  Widget _getSmallTitle(String title){
-    return Container(
-        alignment: Alignment.center,
-        padding: const EdgeInsets.only(left: 3, right: 3),
-        decoration: const BoxDecoration(color: Colors.black),
-        child: Text(title,
-            style: const TextStyle(
-                fontSize:11,
-                color: Colors.white,
-                fontWeight: FontWeight.w700))
-    );
-  }
-
-
-  Widget _compass() {
-
-    return Obx(() {
-      final radians = controller.compassRadians.value;
-
-      return Compass2(
-        compassRadians: radians,
-        mapNorthRadians: radians,
-        nextPointRadians: isShowNextPointer? controller.nextPointRadians.value: null,
-        level: 1,
-        showDegrees: vec.degrees(radians).compassDegrees,
-        diameter: compassDiameter,
-        nextPointImage: Image.asset('assets/images/im_compass_next_arrow2.png'),
-        nextPointHeight: 100,
-        degreeColor: Colors.white,
-        plantSrc: 'assets/images/im_compass_no_map.png',
-      );
-    } );
-  }
-
-
-  Widget _heartRate() {
-    return Obx(() => Row(
-      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
-      children: [
-        wHrp(),
-        Container(
-            width: 1,
-            height: 53,
-            color: Colors.white.withAlpha((255 * 0.3).round())),
-        wHr(),
-      ],
-    ));
-  }
-
-  Widget wHrp() {
-    final hrp = controller.heartRatePercent.value.round();
-    return Row(
-      mainAxisSize: MainAxisSize.min,
-      crossAxisAlignment: CrossAxisAlignment.start,
-      children: [
-        Text('$hrp',
-            style: const TextStyle(fontSize: 43, fontWeight: FontWeight.w700)),
-        const Text('%',
-            style: TextStyle(fontSize: 20, fontWeight: FontWeight.w700))
-      ],
-    );
-  }
-
-  Widget wHr() {
-    return Row(
-      mainAxisSize: MainAxisSize.min,
-      crossAxisAlignment: CrossAxisAlignment.start,
-      children: [
-        Text('${controller.heartRate.value}',
-            style: const TextStyle(fontSize: 43, fontWeight: FontWeight.w700)),
-        Padding(
-            padding: const EdgeInsets.only(top: 5),
-            child: Image.asset('assets/images/ic_heart.png', height: 14.4))
-      ],
-    );
-  }
-
-  Widget _sports() {
-    const style = TextStyle(fontSize: 15.24, fontWeight: FontWeight.w500);
-
-    return Obx(() => Row(
-      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
-      children: [
-        wSport(
-            '${controller.stepCount.value}', 'assets/images/ic_step_count.png',
-            textStyle: style),
-        wSport(controller.kCal.value.toStringAsFixed(1),
-            'assets/images/ic_kcal.png',
-            textStyle: style),
-        wSport(
-            controller.ck.value.toStringAsFixed(1), 'assets/images/ic_ck.png',
-            textStyle: style),
-        wSport(controller.ei.round().toString(), 'assets/images/ic_ei.png',
-            textStyle: style),
-      ],
-    ));
-  }
-
-  Widget _bottomBar() {
-    return Padding(
-        padding: const EdgeInsets.only(bottom: 20, left: 20, right: 20),
-        child: Row(
-          mainAxisAlignment: MainAxisAlignment.spaceBetween,
-          crossAxisAlignment: CrossAxisAlignment.end,
-          children: [
-            isEnableRuler?
-            GestureDetector(
-                onTap: _onSetMapScale,
-                child: Image.asset('assets/images/btn_ruler_scale_no_map.png',
-                  width: 46,
-                )): const SizedBox(),
-            bottomCenterButton,
-            isEnableRuler?
-
-                GestureDetector(
-                onTap: () => controller.isNoMapRulerScaleMode.value = true,
-                child: Image.asset(
-                  'assets/images/btn_ruler_no_map.png',
-                  width: 46,
-                )): const SizedBox()
-          ],
-        ));
-  }
-
-  _onSetMapScale() {
-    var value = controller.userSetMapScale.value?.toString() ?? '';
-
-    Get.dialog(AlertDialog(
-      title: const Text('设置比例尺'),
-      content: Row(
-        children: [
-          const Text(
-            '1 :',
-            style: TextStyle(fontSize: 16),
-          ),
-          const SizedBox(
-            width: 6,
-          ),
-          SizedBox(
-              width: 120,
-              child: TextField(
-                  onChanged: (v) {
-                    value = v;
-                  },
-                  keyboardType: TextInputType.number,
-                  controller: TextEditingController.fromValue(
-                      TextEditingValue(text: value)))),
-        ],
-      ),
-      actions: [
-        TextButton(
-            onPressed: () {
-              Get.back();
-            },
-            child: const Text('取消')),
-        TextButton(
-            onPressed: () {
-              controller.userSetMapScale.value = double.tryParse(value)!;
-              Get.back();
-            },
-            child: const Text('确定')),
-      ],
-    ));
-  }
-}
-

+ 0 - 49
lib/view/ingame/game_compass/game_compass_button.dart

@@ -1,49 +0,0 @@
-import 'package:flutter/material.dart';
-
-
-
-Widget buttonInfo({required VoidCallback onPressed}){
-  return _topButton(
-      onPressed: onPressed,
-      src: 'assets/images/btn_info_no_map.png'
-  );
-}
-
-Widget buttonCheckedCP({required VoidCallback onPressed}){
-  return _topButton(
-      onPressed: onPressed,
-      src: 'assets/images/btn_past_cp_no_map.png'
-  );
-}
-
-Widget buttonBrightness({required VoidCallback onPressed}){
-  return _topButton(
-      onPressed: onPressed,
-      src: 'assets/images/btn_brightness_no_map.png'
-  );
-}
-
-Widget buttonSettings({required VoidCallback onPressed}){
-  return _topButton(
-      onPressed: onPressed,
-      src: 'assets/images/btn_settings_no_map.png'
-  );
-}
-Widget buttonExit({required VoidCallback onPressed}){
-  return _topButton(
-      onPressed: onPressed,
-      src: 'assets/images/btn_exit_no_map.png'
-  );
-}
-
-
-Widget _topButton({required VoidCallback onPressed, required String src}){
-  return GestureDetector(
-      onTap: onPressed,
-      child: Image.asset(
-        src,
-        width: 34,
-        height: 34,
-      )
-  );
-}

+ 0 - 27
lib/view/ingame/game_compass/game_compass_top4_data.dart

@@ -1,27 +0,0 @@
-import 'package:flutter/material.dart';
-
-
-class GameCompassTop4Data extends StatelessWidget{
-  const GameCompassTop4Data({super.key, required this.child, required this.title});
-  final Widget child;
-  final String title;
-
-  @override
-  Widget build(BuildContext context) {
-    return Expanded(
-        child:
-            Container(
-              height: 55,
-              alignment: Alignment.center,
-              decoration: BoxDecoration(
-                  color: const Color(0x29ffffff),
-                  border: Border.all(
-                      color: const Color(0x43ffffff), width: 1.09),
-                  borderRadius: BorderRadius.circular(2.18)),
-              child: child,
-            ),
-    );
-  }
-
-
-}

+ 0 - 138
lib/view/ingame/game_guardian/guardian_controller.dart

@@ -1,138 +0,0 @@
-import 'dart:async';
-import 'package:dart_jts/dart_jts.dart';
-import 'package:trackoffical_app/model/game_person_data.dart';
-import 'package:trackoffical_app/service/game/game_instance_guardian.dart';
-import 'package:trackoffical_app/service/game/game_manager_service.dart';
-import '../../../model/game_map.dart';
-import '../../../model/m_position.dart';
-import '../../../service/app.dart';
-import '../layer/layer_controller.dart';
-
-class GuardianControllerMock extends LayerController {
-  var instance = GameInstanceGuardian(underGuardianId: -1);
-  final selectedPersonIndex = 0.obs;
-  final Rx<int?> lockUnderGuardianToCenterUserId = Rx(null);
-  final Rx<MPosition?> guardianPosition = Rx(null);
-  final Rx<Offset?> guardianPositionOnMap = Rx(null);
-  final isShowGuardian = true.obs;
-  final isShowRoute = true.obs;
-  StreamSubscription<MPosition>? _subscriptionPosition;
-
-
-  GamePersonData? get selectedPersonData {
-    if (instance.gamePersonData.isEmpty) {
-      return null;
-    }
-    var i = instance.gamePersonData.length - 1;
-
-    if (selectedPersonIndex.value < i) {
-      i = selectedPersonIndex.value;
-    }
-    return instance.gamePersonData[i];
-  }
-
-  void setUserById(int userId){
-    for(var i=0; i< instance.gamePersonData.length;i++){
-      if(instance.gamePersonData[i].userId==userId){
-        selectedPersonIndex.value =i;
-        break;
-      }
-    }
-  }
-  GamePersonData? getUserById(int userId){
-    for(var i=0; i< instance.gamePersonData.length;i++){
-      if(instance.gamePersonData[i].userId==userId){
-        return instance.gamePersonData[i];
-      }
-    }
-    return null;
-  }
-
-  void lockUnderGuardianToCenter(GamePersonData person){
-    if(lockUnderGuardianToCenterUserId.value!=null){
-      lockUnderGuardianToCenterUserId.value=null;
-      isEnableUserTouchTranslation=true;
-    }else{
-      lockUnderGuardianToCenterUserId.value = person.userId;
-      isEnableUserTouchTranslation=false;
-    }
-  }
-  void moveScreenCenterToGuardianLocation(){
-    final gp = guardianPositionOnMap.value;
-    if(gp!= null){
-      moveOnMapPointToScreen(gp, mapRotateCenter.value);
-    }
-  }
-
-  @override
-  GameMap? get gameMap => instance.gameMapData;
-
-  @override
-  void onMapSizeChange(Size size) {
-    super.onMapSizeChange(size);
-    mapRotateCenter.value = Offset(size.width / 2, size.height / 2);
-  }
-
-  @override
-  void onClose() {
-    super.onClose();
-    guardianPosition.close();
-  }
-}
-
-class GuardianController extends GuardianControllerMock {
-  @override
-  GameInstanceGuardian get instance {
-    final i = GameManagerService.to.instance!;
-    if (i is! GameInstanceGuardian) {
-      throw RuntimeException('未开始监控');
-    }
-    return i;
-  }
-
-  Timer? _timerUnderGuardianToScreenCenter;
-
-  @override
-  void onReady() {
-    super.onReady();
-    final userId = Get.arguments;
-    if(userId is int){
-      setUserById(userId);
-    }
-    final locationStream = App.to.locationStream;
-    App.to.locationStart(500.milliseconds, 0);
-
-    _subscriptionPosition?.cancel();
-    _subscriptionPosition=locationStream.listen((event) {
-      guardianPosition.value=event;
-
-      gameMap?.worldToPixel(event).then((offset){
-        guardianPositionOnMap.value= offset;
-      });
-    });
-
-    // guardianPosition.bindStream(Sensor.locationStream.map((event) => event.toModel()));
-    _timerUnderGuardianToScreenCenter = Timer.periodic(200.milliseconds, (timer) {
-      final userId = lockUnderGuardianToCenterUserId.value;
-      if(userId!= null){
-         final user = getUserById(userId);
-         if(user!= null){
-           var p = user.myPositionOnMap;
-           if(p!= null){
-              moveOnMapPointToScreen(p, mapRotateCenter.value);
-           }
-         }
-      }
-    });
-  }
-
-
-  @override
-  void onClose() {
-    super.onClose();
-    _timerUnderGuardianToScreenCenter?.cancel();
-    _subscriptionPosition?.cancel();
-    GameManagerService.to.instanceStop();
-    App.to.locationStop();
-  }
-}

+ 0 - 162
lib/view/ingame/game_guardian/guardian_watch_game_view.dart

@@ -1,162 +0,0 @@
-import 'package:trackoffical_app/model/game_map.dart';
-import 'package:trackoffical_app/model/game_person_data.dart';
-import 'package:trackoffical_app/screen.dart';
-import 'package:trackoffical_app/service/api.dart';
-import 'package:trackoffical_app/service/app.dart';
-import 'package:trackoffical_app/service/database.dart';
-import 'layer_under_guardian.dart';
-import '../layer/layer_cp.dart';
-import 'package:trackoffical_app/widget/my_position_point.dart';
-import '../../../service/sport_wear.dart';
-import '../layer/layer_trace.dart';
-import 'layer_front_ui.dart';
-import 'guardian_controller.dart';
-import '../layer/layer_controller.dart';
-import '../layer/layer_map_touch.dart';
-import '../layer/layer_map.dart';
-import '../../../service/game/game_instance_guardian.dart';
-import 'package:trackoffical_app/pb.dart' as pb;
-
-
-
-class GuardianWatchGameView extends GetView<LayerController>{
-  const GuardianWatchGameView({
-    super.key});
-
-  static  final _pointColorList = <Color>[
-    Colors.orange,
-    Colors.blue,
-    Colors.red,
-  ];
-
-
-  static Bindings bindings() {
-    return BindingsBuilder(() {
-      Get.lazyPut<LayerController>(() => GuardianController());
-    });
-  }
-
-
-
-  @override
-  Widget build(BuildContext context) {
-    final c = controller;
-    if(c is! GuardianControllerMock){
-      throw UnimplementedError('${c.runtimeType} is not GuardianController');
-    }
-
-    return Obx((){
-      final children = <Widget>[];
-      if(c.mapWidgetSize.value != null){
-        final selectedPerson = c.selectedPersonData;
-
-        children.add(const LayerMap());
-        children.add(Container(color: Colors.white.withAlpha(125)));
-        var i = 0;
-        for(var person in c.instance.gamePersonData){
-          children.add(LayerTrace(
-              onMapTrace: person.myPositionOnMapHistory,
-              color: _pointColorList[i]));
-          i++;
-          if(i> _pointColorList.length-1){
-            i=_pointColorList.length-1;
-          }
-        }
-
-        if(selectedPerson!= null && c.isShowRoute.value){
-          children.add(LayerCP(
-              isHideRouteBeforeStart: false,
-              wantList: selectedPerson.controlPointWantSequence
-          ));
-        }
-
-        if(c.isShowGuardian.value){
-          children.add(_LayerGuardianPosition());
-        }
-
-        children.addAll([
-          const LayerMapTouch(),
-          LayerUnderGuardian(_pointColorList),
-        ]);
-      }
-
-
-
-      children.addAll([
-        const LayerFrontUI()
-      ]);
-
-
-      return Scaffold(
-        backgroundColor: const Color(0xffd6d6d6),
-        body: Stack(
-          key: c.mapWidgetKey,
-          alignment: Alignment.topLeft,
-          children: children
-        ),
-      );
-    });
-  }
-}
-
-class _LayerGuardianPosition extends GetView<LayerController>{
-  @override
-  Widget build(BuildContext context) {
-    final c = controller;
-    if (c is! GuardianControllerMock) {
-      throw UnimplementedError('${c.runtimeType} is not GuardianController');
-    }
-
-    return Obx((){
-      var p = c.guardianPositionOnMap.value;
-      if (p == null) {
-        return const SizedBox();
-      }
-      p = c.mapOffsetToScreen(p);
-
-      return Stack(
-            children: [
-              SizedBox(width: context.width, height: context.height),
-              MyPositionPoint(offset: p, color: Colors.blue)
-            ]);
-    });
-  }
-}
-
-void main()async{
-  Get.put<App>(App());
-  Get.put(SportWearService());
-  Get.put<DatabaseService>(DatabaseService());
-  Get.put<ApiService>(ApiService());
-  await App.to.init();
-  await DatabaseService.to.init();
-  await ApiService.to.init();
-
-  final data = GameInstanceGuardian(underGuardianId: -1);
-  data.gameMapData = (pb.NetImage()
-    ..md5= [53, 52, 51, 52, 53, 51, 49, 50, 50, 51, 50, 51, 49, 49]
-  ).toGameMap();
-  data.gamePersonData.add(GamePersonData()
-    ..userName='赵小曼'
-    ..myPositionOnMapHistory.addAll([
-      Offset(3000, 4000),
-      Offset(3000, 4100),
-      Offset(3000, 4200),
-      Offset(3100, 4200),
-      Offset(3200, 4200),
-      Offset(3300, 4200),
-      Offset(3400, 4200),
-      Offset(3500, 4200),
-      Offset(3600, 4200),
-      Offset(3700, 4200),
-      Offset(3800, 4200),
-
-    ]));
-  await data.init();
-  final c = GuardianControllerMock();
-  c.instance = data;
-  c.guardianPositionOnMap.value =  Offset(4800, 5200);
-
-  Get.put<LayerController>(c);
-  runPreview(GuardianWatchGameView());
-}

+ 0 - 302
lib/view/ingame/game_guardian/layer_front_ui.dart

@@ -1,302 +0,0 @@
-import 'package:trackoffical_app/generated/assets.dart';
-import 'package:trackoffical_app/screen.dart';
-import 'package:trackoffical_app/utils.dart';
-import 'package:trackoffical_app/view/ingame/dialog/dialog_base.dart';
-import '../layer/layer_controller.dart';
-import 'guardian_controller.dart';
-import '../m_icon_button.dart';
-
-class LayerFrontUI extends GetView<LayerController> {
-  const LayerFrontUI({super.key});
-
-  @override
-  Widget build(BuildContext context) {
-    final pH = 4.96.wp;
-
-    return Padding(
-        padding: EdgeInsets.fromLTRB(
-            pH, MediaQuery.of(context).padding.top + 5.0.wp, pH, 11.19.wp),
-        child: Stack(
-          children: [
-            Column(
-              children: [
-                Row(
-                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                  crossAxisAlignment: CrossAxisAlignment.start,
-                  children: [
-                    _ButtonBar(),
-                    GestureDetector(
-                      onTap: () => Get.back(),
-                      child: Image.asset(Assets.imagesBtnMapBack,
-                          height: 46.0, fit: BoxFit.fitHeight),
-                    )
-                  ],
-                ),
-                const Spacer(),
-                _InfoCard(),
-              ],
-            )
-          ],
-        ));
-  }
-}
-
-class _ButtonBar extends GetView<LayerController> {
-  @override
-  Widget build(BuildContext context) {
-    final c = controller;
-    if (c is! GuardianControllerMock) {
-      return const SizedBox();
-    }
-
-
-    return Column(
-      mainAxisSize: MainAxisSize.min,
-      children: [
-        _btnLocUnderGuardian(),
-        _btnLocUnderGuardianLock(c),
-        MIconButton(
-            icon: Image.asset(Assets.imagesBtnMapAdd),
-            onPressed: () {
-              controller.mapDoScale(1.2);
-            }),
-        MIconButton(
-            icon: Image.asset(Assets.imagesBtnMapMinus),
-            onPressed: () {
-              controller.mapDoScale(0.8);
-            }),
-        _btnShowRoute(),
-        _btnLocateGuardian(),
-        _btnShowGuardian()
-      ],
-    );
-  }
-
-  Widget _btnLocUnderGuardian(){
-    return Obx((){
-      final c = controller;
-      if (c is! GuardianControllerMock) {
-        return const SizedBox();
-      }
-      final person = c.selectedPersonData;
-      final position = person?.myPositionOnMap;
-
-      return MIconButton(
-          src: Assets.imagesBtnLocUnderGuardian,
-          onPressed: position!=null?(){
-            c.moveOnMapPointToScreen(position, c.mapRotateCenter.value);
-          }: null);
-    });
-  }
-
-  Widget _btnLocUnderGuardianLock(GuardianControllerMock c){
-    return Obx((){
-      final person = c.selectedPersonData;
-
-      return MIconButton(
-          src: Assets.imagesBtnLocUnderGuardianUnlock,
-          selectedSrc: Assets.imagesBtnLocUnderGuardianLock,
-          isSelected: person?.userId==c.lockUnderGuardianToCenterUserId.value,
-          onPressed: person!=null?(){
-            c.lockUnderGuardianToCenter(person);
-          } :null);
-    });
-  }
-  Widget _btnShowRoute(){
-    return Obx((){
-      final c = controller;
-      if (c is! GuardianControllerMock) {
-        return const SizedBox();
-      }
-
-      return MIconButton(
-          src: Assets.imagesBtnShowRouteSwitch,
-          isSelected: c.isShowRoute.value,
-          onPressed: ()=>c.isShowRoute.value=!c.isShowRoute.value);
-    });
-  }
-
-  Widget _btnShowGuardian(){
-    return Obx((){
-      final c = controller;
-      if (c is! GuardianControllerMock) {
-        return const SizedBox();
-      }
-
-      return MIconButton(
-          src: Assets.imagesBtnGuardianLocationSwitch,
-          isSelected: c.isShowGuardian.value,
-          onPressed: ()=>c.isShowGuardian.value=!c.isShowGuardian.value);
-    });
-  }
-  Widget _btnLocateGuardian(){
-    final c = controller;
-    if (c is! GuardianControllerMock) {
-      return const SizedBox();
-    }
-
-    return Obx((){
-      final c = controller;
-      if (c is! GuardianControllerMock) {
-        return const SizedBox();
-      }
-
-      return MIconButton(
-          src: Assets.imagesBtnGuardianLocation,
-          onPressed: c.isShowGuardian.value? c.moveScreenCenterToGuardianLocation :null);
-    });
-  }
-}
-
-class _InfoCard extends GetView<LayerController> {
-  @override
-  Widget build(BuildContext context) {
-    return Obx(() {
-      final c = controller;
-      if (c is! GuardianControllerMock) {
-        return const SizedBox();
-      }
-      final personData = c.selectedPersonData;
-      if (personData == null) {
-        return const SizedBox();
-      }
-      final nextWantCP = personData.nextWantPoint;
-      var nextWantCPDistance = '--';
-      var nextWantCPDistanceD = personData.nextWantCPDistanceKmShow;
-      if(nextWantCPDistanceD!=null){
-        nextWantCPDistance = nextWantCPDistanceD.m.toInt().toString();
-      }
-      String? underGuardianDis;
-      if(c.isShowGuardian.value){
-        underGuardianDis = '--';
-
-        final p1 = c.guardianPosition.value;
-        final p2 = personData.myPosition;
-
-        if(p1!= null && p2!= null){
-          underGuardianDis = p2.distance(p1).m.toStringAsFixed(0);
-        }
-      }
-
-
-
-      return Container(
-        decoration: BoxDecoration(
-            color: Colors.white,
-            borderRadius: BorderRadius.circular(3.82.wp),
-            boxShadow: [
-              BoxShadow(color: const Color(0x45000000), blurRadius: 1.53.wp)
-            ]),
-        padding: EdgeInsets.all(3.56.wp),
-        width: context.width,
-        child: Column(
-          mainAxisSize: MainAxisSize.min,
-          children: [
-            Row(
-              mainAxisAlignment: MainAxisAlignment.spaceBetween,
-              children: [
-                Column(
-                  mainAxisSize: MainAxisSize.min,
-                  crossAxisAlignment: CrossAxisAlignment.start,
-                  children: [
-                    Text.rich(TextSpan(
-                        text: personData.userName,
-                        style: TextStyle(
-                            fontSize: 6.62.wp, fontWeight: FontWeight.w500),
-                        children: [
-
-                          // TextSpan(text: '  距离监护人米',
-                          TextSpan(
-                            text: underGuardianDis!=null?'  距离监护人$underGuardianDis米': ' ',
-                            style: TextStyle(
-                                fontSize: 3.56.wp,
-                                fontWeight: FontWeight.w400,
-                                color: context.theme.colorScheme.primary),
-                          )
-                        ])),
-                    Text(
-                      personData.duration.value.toAppString(),
-                      style: TextStyle(
-                          fontSize: 6.11.wp, fontFamily: 'sa-digital-number'),
-                    )
-                  ],
-                ),
-                bean(personData.beanCount.value, 4.5.wp),
-              ],
-            ),
-            const Divider(),
-            Row(
-              mainAxisAlignment: MainAxisAlignment.spaceBetween,
-              children: [
-                _wPointText(
-                    '打点${personData.checkedCount}/${personData.validCPAllNum}'),
-                _wPointText(
-                    '里程${personData.myPositionHistoryLen.value}'),
-                _wPointText(
-                    '配速${personData.pacePerKm.value.toMinSecondString()}'),
-              ],
-            ),
-            SizedBox(height: 2.0.wp),
-            Row(
-              mainAxisAlignment: MainAxisAlignment.spaceBetween,
-              children: [
-                _wCardText('实时心率', "${personData.heartRate.value}",
-                    color:  personData.heartRatePercent.value.round().toHRPColor()),
-                _wCardText(
-                    '目标', nextWantCP != null ? '${nextWantCP.snString}点' : ''),
-                _wCardText('点距(米)', nextWantCPDistance),
-                _wCardText('步数', '${personData.stepCount.value}'),
-                _wCardText('消耗热量', personData.kCal.value.toStringAsFixed(1)),
-              ],
-            )
-          ],
-        ),
-      );
-    });
-  }
-}
-
-Widget _wPointText(String text) {
-  return Row(
-    mainAxisSize: MainAxisSize.min,
-    children: [
-      Container(
-        width: 2.0.wp,
-        height: 2.0.wp,
-        decoration: const BoxDecoration(
-            shape: BoxShape.circle, color: Color(0xffff870d)),
-      ),
-      Text(
-        text,
-        style: TextStyle(fontSize: 4.0.wp, fontWeight: FontWeight.w500),
-      ),
-    ],
-  );
-}
-
-Widget _wCardText(String title, String value, {Color? color}) {
-  final valueColor = color != null ? Colors.white : Colors.black;
-  final titleColor = color != null ? Colors.white : Colors.grey;
-
-  return Container(
-    width: 13.99.wp,
-    height: 16.03.wp,
-    decoration: BoxDecoration(
-      color: color ?? const Color(0xfff9f9f9),
-      borderRadius: BorderRadius.circular(1.53.wp),
-    ),
-    child: Column(
-      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
-      children: [
-        Text(
-          title,
-          style: TextStyle(fontSize: 2.54.wp, color: titleColor),
-        ),
-        Text(
-          value,
-          style: TextStyle(fontSize: 4.0.wp, color: valueColor),
-        )
-      ],
-    ),
-  );
-}

+ 0 - 99
lib/view/ingame/game_guardian/layer_under_guardian.dart

@@ -1,99 +0,0 @@
-import 'package:trackoffical_app/screen.dart';
-import 'widget_point.dart';
-import '../../../model/game_person_data.dart';
-import '../layer/layer_controller.dart';
-import '../layer/layer_trace.dart';
-import 'guardian_controller.dart';
-
-
-class LayerUnderGuardian extends GetView<LayerController> {
-  LayerUnderGuardian(this.pointColorList, {super.key});
-
-  final pointWidth = 43.0.wp;
-  final pointHeight = 29.0.wp;
-  final List<Color> pointColorList;
-
-  @override
-  Widget build(BuildContext context) {
-    final c = controller;
-    if(c is! GuardianControllerMock){
-      return const SizedBox();
-    }
-
-    return Obx((){
-      final children = <Widget>[
-        SizedBox(width: context.width, height: context.height)
-      ];
-
-      var i = 0;
-
-
-      for(var person in c.instance.gamePersonData){
-        var p = person.myPositionOnMap;
-
-        if(p != null){
-          p = c.mapOffsetToScreen(p);
-          children.add(Positioned(
-              left: p.dx - pointWidth/2,
-              top: p.dy - pointHeight,
-              child:  wPoint(pointColorList[i], person, (){
-                c.setUserById(person.userId);
-              })));
-        }
-
-        i++;
-        if(i> pointColorList.length-1){
-          i=pointColorList.length-1;
-        }
-      }
-
-
-      return Stack(
-        children: children,
-      );
-    });
-  }
-
-  Widget wPoint(Color color, GamePersonData data, VoidCallback onClick){
-    final nextWantCP = data.nextWantPoint;
-    var text = '';
-    if(nextWantCP!= null){
-      text = '正前往${nextWantCP.snString}点';
-    }
-
-    return GestureDetector(
-      onTap: onClick,
-      child: SizedBox(
-        width: pointWidth,
-        height: pointHeight,
-        child: Column(
-          mainAxisAlignment: MainAxisAlignment.spaceBetween,
-          children: [
-            Container(
-              height: 5.85.wp,
-              width: pointWidth,
-              decoration: BoxDecoration(color: color, borderRadius: BorderRadius.circular(3.0.wp)),
-              padding: EdgeInsets.fromLTRB(2.6.wp, 0, 2.6.wp, 0),
-              child: Row(
-                mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                crossAxisAlignment: CrossAxisAlignment.center,
-                children: [
-                  SizedBox(width: 13.0.wp,
-                      child: Text(
-                          data.userName,
-                          style: TextStyle(fontSize: 3.5.wp, color: Colors.white),
-                        overflow: TextOverflow.clip,
-                      )),
-                  Text(text, style: TextStyle(fontSize: 3.5.wp, color: Colors.black)),
-                  Icon(Icons.arrow_forward_ios_rounded, size: 3.0.wp, color: Colors.white)
-                ],
-              ),
-            ),
-            WidgetPoint(width: 14.68.wp, height: 21.57.wp, color: color, imageBytes: data.userHead.value.data)
-          ],
-        ),
-      ),
-    );
-  }
-
-}

+ 0 - 109
lib/view/ingame/game_guardian/widget_point.dart

@@ -1,109 +0,0 @@
-import 'dart:typed_data';
-
-import 'package:flutter/material.dart';
-import 'package:trackoffical_app/generated/assets.dart';
-import 'package:trackoffical_app/screen.dart';
-
-class WidgetPoint extends StatelessWidget {
-  final double width;
-  final double height;
-  final Color color;
-  final Uint8List? imageBytes;
-
-  const WidgetPoint(
-      {super.key,
-      required this.width,
-      required this.height,
-      required this.color,
-        this.imageBytes
-      });
-
-  @override
-  Widget build(BuildContext context) {
-    final headRadius = width * 0.36;
-    final headMargin = width/2 - headRadius;
-
-    DecorationImage? image;
-    if(imageBytes!= null){
-      image = DecorationImage(image: MemoryImage(imageBytes!));
-    }else{
-      image = const DecorationImage(image: AssetImage(Assets.imagesImDefaultHead), fit: BoxFit.fill);
-    }
-
-    return Stack(
-      children: [
-        SizedBox(
-            width: width,
-            height: height,
-            child: CustomPaint(painter: _Painter(color))),
-        Positioned(
-          left: headMargin,
-          top: headMargin,
-          child: Container(
-            width: headRadius*2,
-            height: headRadius*2,
-            decoration: BoxDecoration(
-                border: Border.all(color: Colors.white, width: 0.25.wp),
-                shape: BoxShape.circle,
-                image: image,
-            ),
-          )
-        )
-
-      ],
-    );
-  }
-}
-
-class _Painter extends CustomPainter {
-  _Painter(this.color);
-
-  final Color color;
-  final _paint = Paint();
-
-  @override
-  void paint(Canvas canvas, Size size) {
-    final lineWidth = size.width * 0.04;
-    draw(canvas, size, Colors.white, 0);
-    draw(canvas, size, color, lineWidth);
-  }
-
-  void draw(Canvas canvas, Size size, Color color, double lineWidth) {
-    _paint.color = color;
-    _paint.style = PaintingStyle.fill;
-    final radius = (size.width - lineWidth * 2) / 2;
-    canvas.drawCircle(
-        Offset(radius + lineWidth, radius + lineWidth), radius, _paint);
-
-    final w = size.width / 3 - lineWidth * 2;
-
-    final path = Path();
-    var x = lineWidth;
-    var y = lineWidth;
-    x = (size.width - w) / 2;
-    y += radius * 1.5;
-
-    path.moveTo(x, y);
-    x += w;
-    path.lineTo(x, y);
-    x = size.width / 2;
-    y = size.height - lineWidth * 2;
-    path.lineTo(x, y);
-    path.close();
-    canvas.drawPath(path, _paint);
-  }
-
-  @override
-  bool shouldRepaint(covariant CustomPainter oldDelegate) {
-    return false;
-  }
-}
-
-void main() {
-  runPreview(Center(
-      child: WidgetPoint(
-    width: 140,
-    height: 210,
-    color: Colors.red,
-  )));
-}

+ 0 - 153
lib/view/ingame/game_orienteering_assistant/game_orienteering_assistant_view.dart

@@ -1,153 +0,0 @@
-import 'package:trackoffical_app/screen.dart';
-import 'package:trackoffical_app/service/game/game_instance_orienteering_assistant.dart';
-import 'package:trackoffical_app/utils.dart';
-import 'package:trackoffical_app/view/game_settings.dart';
-import 'package:trackoffical_app/view/ingame/instance_view.dart';
-import 'package:screen_brightness/screen_brightness.dart';
-import '../../../logger.dart';
-import '../../../service/app.dart';
-// import '../../info_help.dart';
-import '../game_compass/game_compass_base.dart';
-import 'package:get/get.dart';
-
-
-Widget gameOrienteeringAssistantView(GameInstanceOrienteeringAssistant instance){
-  return InstanceView(
-      instance: instance,
-      child: GameOrienteeringAssistantContent(instance: instance)
-  );
-}
-
-
-
-class GameOrienteeringAssistantContent extends StatefulWidget{
-  const GameOrienteeringAssistantContent({super.key, required this.instance});
-  final GameInstanceOrienteeringAssistant instance;
-  @override
-  State<StatefulWidget> createState() {
-    return _ViewState();
-  }
-}
-
-
-class _ViewState extends State<GameOrienteeringAssistantContent>{
-
-
-  @override
-  Widget build(BuildContext context) {
-
-    return GameCompassBase(controller: controller,
-        top4data: top4Data(),
-        topButtons: topButtons(),
-        process: null,
-        isShowNextPointer: false,
-        isEnableRuler: true,
-        bottomCenterButton: bottomCenterButton(),
-      compassDiameter: 66.wp,
-    );
-  }
-
-  bool get isBrightnessMax =>
-      App.to.userProfile.isEnableInGameBrightnessMax.val;
-  Future<void> setIsBrightnessMax(bool v) async {
-    App.to.userProfile.isEnableInGameBrightnessMax.val = v;
-    if (v) {
-      await ScreenBrightness().setScreenBrightness(1);
-    } else {
-      await ScreenBrightness().resetScreenBrightness();
-    }
-  }
-
-
-  List<Widget> topButtons(){
-    return [
-      // buttonInfo(onPressed: () => Get.to(() => const InfoHelp())),
-      buttonBrightness(onPressed: _onBrightness),
-      buttonSettings(onPressed: _toSettings),
-      buttonExit(onPressed: _exit),
-    ];
-  }
-
-
-  void _onBrightness(){
-    setIsBrightnessMax(!isBrightnessMax);
-  }
-  void _toSettings(){
-    Get.to(()=>const GameSettingsView());
-  }
-  void _exit(){
-    Get.back();
-  }
-
-
-  List<GameCompassTop4Data> top4Data() {
-    return [
-      GameCompassTop4Data(
-          title: '里程',
-          child: Obx(() => Text(distance.value.toString())) ),
-      GameCompassTop4Data(
-          title: '配速',
-          child: Obx(() => Text(pace.value.toMinSecondString()))),
-    ];
-  }
-
-  Widget bottomCenterButton(){
-    const color = Color(0x57ffffff);
-
-    return Obx((){
-      final isStart = widget.instance.isStart.value;
-
-
-      return GestureDetector(
-        onTap: widget.instance.onSwitch,
-        child: Container(
-          width: 25.5.wp,
-          height: 10.5.wp,
-          decoration: BoxDecoration(
-              color: color.withAlpha(130),
-              borderRadius: BorderRadius.circular(1.67.wp),
-            border: Border.all(color: color, width: 0.28.wp)
-          ),
-          alignment: Alignment.center,
-          child: Text(isStart?'停止':'开始', style: TextStyle(fontSize: 5.wp)),
-        ),
-      );
-    });
-  }
-
-  @override
-  void initState() {
-    final instance = widget.instance;
-    final sw = widget.instance.plugSportWear;
-
-    rxBindRx(dst: controller.duration, src: instance.duration);
-    rxBindRx(dst: controller.compassRadians, src: instance.compassRadiansSrc);
-    rxBindRx(dst: distance, src: instance.distance);
-    rxBindRx(dst: pace, src: instance.pace);
-    rxBindRx(dst: controller.heartRatePercent, src: sw.heartRatePercent);
-    rxBindRx(dst: controller.heartRate, src: sw.heartRate);
-    rxBindRx(dst: controller.stepCount, src: sw.stepCount);
-    rxBindRx(dst: controller.kCal, src: sw.kCal);
-    rxBindRx(dst: controller.ck,  src: sw.ck);
-    rxBindRx(dst: controller.ei, src: sw.ei);
-    super.initState();
-  }
-
-  @override
-  void dispose() {
-    for(final one in _rx){
-      one.close();
-    }
-    super.dispose();
-  }
-
-  void rxBindRx<T>({required Rx<T> dst,required Rx<T> src}){
-    _rx.add(dst);
-    dst.bindStream(src.stream);
-  }
-
-  final controller = GameCompassController();
-  final distance = 0.meter.obs;
-  final pace = 0.seconds.obs;
-  final _rx = <Rx>[];
-}

+ 0 - 140
lib/view/ingame/game_std/button_punch.dart

@@ -1,140 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:get/get.dart';
-import 'package:trackoffical_app/generated/assets.dart';
-import 'package:trackoffical_app/service/app.dart';
-import 'package:rive/rive.dart';
-import 'package:vibration/vibration.dart';
-
-class ButtonPunch extends StatefulWidget {
-  const ButtonPunch({
-    super.key,
-    required this.onPressed,
-    required this.isWarn,
-  });
-
-  final VoidCallback? onPressed;
-  final bool isWarn;
-
-  @override
-  State<StatefulWidget> createState() {
-    return ButtonPunchState();
-  }
-}
-
-class ButtonPunchState extends State<ButtonPunch>
-    with SingleTickerProviderStateMixin {
-  late AnimationController _animationController;
-  late Animation<Color?> _animation;
-  var _isActive = true;
-
-  @override
-  void initState() {
-    super.initState();
-
-    _animationController = AnimationController(
-      vsync: this,
-      duration: const Duration(milliseconds: 500),
-      reverseDuration: const Duration(milliseconds: 500),
-    )..repeat(reverse: true);
-    _animation = ColorTween(begin: Colors.white, end: Colors.red)
-        .animate(_animationController)
-        ..addListener(() {
-        setState(() {
-          // The state that has changed here is the animation object’s value.
-        });
-      });
-
-    loopVibration();
-  }
-
-  Future<void> loopVibration() async{
-    while(_isActive){
-      await Future.delayed(500.milliseconds);
-      if(widget.isWarn){
-        await App.to.vibrate(duration: 100, repeat: 1);
-      }
-    }
-  }
-
-
-  @override
-  void didUpdateWidget(covariant ButtonPunch oldWidget) {
-    super.didUpdateWidget(oldWidget);
-
-    final oldEnabled = oldWidget.onPressed != null;
-    final newEnabled = widget.onPressed != null;
-
-    if (oldEnabled != newEnabled) {
-      if (newEnabled) {
-        _animationController.repeat(reverse: true);
-      } else {
-        _animationController.stop();
-      }
-    }
-  }
-
-  @override
-  void dispose() {
-    _animationController.dispose();
-    _isActive=false;
-    super.dispose();
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    final image = widget.onPressed != null? 'assets/images/btn_punch.png': 'assets/images/btn_punch_disable.png';
-
-    final boxShadow = <BoxShadow>[];
-    final children = <Widget>[];
-    if(widget.isWarn){
-      boxShadow.add(BoxShadow(
-          color: Colors.red.withAlpha(150),
-          offset: const Offset(0.0, 0.0), //阴影y轴偏移量
-          blurRadius: 6, //阴影模糊程度
-          spreadRadius: widget.onPressed!= null? 2: 1 //阴影扩散程度
-      ));
-      children.add(const RiveAnimation.asset(Assets.imagesAmPunchButtonFlash, fit: BoxFit.fill));
-    }else{
-      boxShadow.add(BoxShadow(
-          color: Colors.grey.withAlpha(150),
-          offset: const Offset(2.0, 2.0), //阴影y轴偏移量
-          blurRadius: 6, //阴影模糊程度
-          spreadRadius: widget.onPressed!= null? 5: 1 //阴影扩散程度
-      ));
-    }
-
-    children.add(GestureDetector(
-      onTap: widget.onPressed,
-      child: Container(
-        width: 56,
-        height: 56,
-        decoration: BoxDecoration(
-          color: Colors.white,
-          image: DecorationImage(
-              image: AssetImage(image)),
-          borderRadius: BorderRadius.circular(28),
-          boxShadow: boxShadow,
-        ),
-      ),
-    ));
-
-    return SizedBox(height: 90, width: 90, child: Stack(
-      alignment: Alignment.center,
-      children: children,
-    ));
-  }
-}
-void main() async {
-  runApp(Container(
-    color: Colors.white,
-    child: Column(
-      children: [
-        const Spacer(),
-        ButtonPunch(
-          onPressed: () {  },
-          isWarn: false,
-        )
-      ],
-    ) )
-  ) ;
-}

+ 0 - 150
lib/view/ingame/game_std/dialog_finish.dart

@@ -1,150 +0,0 @@
-import 'package:trackoffical_app/pb.dart' as pb;
-import 'package:flutter/material.dart';
-import 'package:get/get.dart';
-import 'package:trackoffical_app/screen.dart';
-import 'package:trackoffical_app/service/app.dart';
-import 'package:trackoffical_app/utils.dart';
-import '../../../generated/assets.dart';
-import '../../../route.dart';
-import '../dialog/dialog_base.dart';
-import '../dialog/dialog_button.dart';
-
-enum _State{
-  success,
-  ok,
-  fail
-}
-void dialogFinishResult(pb.GameDetailReply data) {
-  if(Get.isOverlaysOpen){
-    Get.back();
-  }
-
-  var state = _State.success;
-  var title = '恭喜!挑战成功';
-  var titleColor = const Color(0xFFFF870D);
-  Color? buttonColor = const Color(0xFF017DC7);
-  var soundSrc = Assets.soundFinishSuccess;
-  if(!data.isSuccess){
-    state = _State.ok;
-  }
-  if(!data.isComplete){
-    state=_State.fail;
-  }
-  switch(state){
-    case _State.ok:
-      title = '挑战完成';
-      titleColor = Colors.red;
-      buttonColor = null;
-      soundSrc = Assets.soundFinishOk;
-      break;
-    case _State.fail:
-      title = '挑战失败';
-      titleColor = Colors.red;
-      buttonColor = null;
-      soundSrc = Assets.soundFinishFail;
-      break;
-    default:
-  }
-  App.to.soundPlayAsset(soundSrc);
-
-  final minutes = data.duration.toDuration().inSeconds.toDouble() /
-      Duration.secondsPerMinute;
-  final distanceKm = data.distance.toDouble() / 1000;
-  final kcal = data.calorie.toDouble() / 1000;
-
-  Get.dialog(
-      WillPopScope(
-        onWillPop: () async{
-          _goNext();
-          return false;
-        },
-        child: dialogTitle(
-            title,
-            titleColor,
-            Column(
-              crossAxisAlignment: CrossAxisAlignment.center,
-              children: [
-                Card(
-                  child: Padding(
-                      padding: EdgeInsets.fromLTRB(
-                        41.1.rpx,
-                        10.1.rpx,
-                        41.1.rpx,
-                        10.1.rpx,
-                      ),
-                      child: Column(
-                        children: [
-                          _elem(Assets.imagesIcFinishTime, '总用时',
-                              minutes.toStringAsFixed(1), ' min '),
-                          _elem(Assets.imagesIcFinishTime, '总里程',
-                              distanceKm.toStringAsFixed(1), ' km  '),
-                          _elem(Assets.imagesIcFinishTime, '消耗卡路里',
-                              kcal.toStringAsFixed(1), ' kcal'),
-                          _elem(Assets.imagesIcFinishTime, '脑力值',
-                              data.answerHistory.accuracy.toString(), ' %   '),
-                        ],
-                      )),
-                ),
-                SizedBox(height: 30.0.rpx),
-                Row(
-                  mainAxisSize: MainAxisSize.min,
-                  children: [
-                    Image.asset(Assets.imagesIcBean, height: 103.9.rpx),
-                    Column(
-                      mainAxisSize: MainAxisSize.min,
-                      children: [
-                        Text('X ${data.sysPoint}',
-                            style: TextStyle(fontSize: 53.44.rpx)),
-                        Text('共获得${data.sysPoint}个百味豆',
-                            style: TextStyle(
-                                fontSize: 22.9.rpx,
-                                color: const Color(0xFFaaaaaa))),
-                      ],
-                    )
-                  ],
-                ),
-                SizedBox(height: 30.0.rpx),
-                dialogButton('确定', _goNext, color: buttonColor),
-                SizedBox(height: 30.0.rpx),
-                Text(
-                  '提示:可以在“成就”中查看详细数据',
-                  style: TextStyle(color: Colors.red, fontSize: 28.63.rpx),
-                )
-              ],
-            )),),
-
-      barrierDismissible: false
-  );
-}
-void _goNext(){
-  Get.offAllNamed(RouteName.home);
-}
-
-Widget _elem(String iconSrc, String title, String value, String unit) {
-  final style = TextStyle(
-      fontSize: 45.8.rpx,
-      fontWeight: FontWeight.w500,
-      color: const Color(0xff333333));
-
-  return Padding(
-      padding: EdgeInsets.only(top: 21.0.rpx, bottom: 21.0.rpx),
-      child: Row(
-        children: [
-          Image.asset(iconSrc, height: 45.8.rpx),
-          SizedBox(width: 9.5.rpx),
-          Expanded(
-              child: Text(
-                title,
-                style: style.copyWith(fontSize: 34.35.rpx),
-              )),
-          RichText(
-              text: TextSpan(text: value, style: style, children: [
-                TextSpan(
-                  text: unit,
-                  style: style.copyWith(
-                      fontSize: 19.1.rpx, color: const Color(0xff818181)),
-                ),
-              ]))
-        ],
-      ));
-}

+ 0 - 598
lib/view/ingame/game_std/game_std_controller.dart

@@ -1,598 +0,0 @@
-import 'dart:async';
-import 'dart:io';
-import 'dart:math';
-import 'package:get_storage/get_storage.dart';
-import 'package:trackoffical_app/model/game_map.dart';
-import 'package:trackoffical_app/model/game_person_data.dart';
-import 'package:trackoffical_app/service/app.dart';
-import 'package:trackoffical_app/service/game/game_instance.dart';
-import 'package:trackoffical_app/service/game/game_instance_std/game_instance_std.dart';
-import 'package:trackoffical_app/service/user_profile.dart';
-import 'package:trackoffical_app/utils.dart';
-import 'package:trackoffical_app/view/ingame/game_compass/game_compass_base.dart';
-import 'package:nfc_manager/nfc_manager.dart';
-import 'package:nfc_manager/platform_tags.dart';
-import '../../../generated/assets.dart';
-import '../../../logger.dart';
-import '../../../widget/matrix_gesture_detector.dart';
-import '../dialog/dialog_base.dart';
-import '../dialog/dialog_check_rich2.dart';
-import '../dialog/dialog_check_text.dart';
-import '../dialog/dialog_cp_order_err.dart';
-import 'route_planning.dart';
-import 'dialog_finish.dart';
-import 'package:screen_brightness/screen_brightness.dart';
-import '../../../model/m_control_point.dart';
-import '../../../widget/compass2.dart';
-import '../../game_settings.dart';
-import '../layer/layer_controller.dart';
-export '../layer/layer.dart';
-import 'package:sensor/sensor.dart' as sensor;
-import 'package:vector_math/vector_math_64.dart' as vec;
-import 'utils.dart';
-
-class GameStdController extends LayerController {
-  GameStdController(this.instance);
-
-  void _listenSettings() {
-    final box = GetStorage();
-    cancelListen = box.listen(_updateSettings);
-  }
-
-  void _updateSettings() {
-    final profile = _app.userProfile;
-    isSimpleDashboard.value = profile.gameSettingsSimpleDashboard.value;
-    isEnableRoutePreview.value =profile.gameSettingsRoutePreview.value;
-    isEnableUserLocationState.value = isEnableUserLocation;
-    gameUIMode.value = profile.gameSettingsUIMode.value;
-  }
-
-  bool get isNfcScanUseDialog {
-    final platform = _app.platformInfo;
-    if (platform is PlatformInfoIOS) {
-      if (platform.deviceVersion >= 8) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  bool get isShowCheckCPButton {
-    final next = instance.model.nextWantPoint;
-    final nextPlan = instance.model.nextPlanPoint;
-    return isNfcScanUseDialog ||
-        next?.type == MControlPointType.gps ||
-        nextPlan?.type == MControlPointType.gps;
-  }
-
-  bool get isCheckCPButtonEnable {
-    final next = instance.model.nextWantPoint;
-    final nextPlan = instance.model.nextPlanPoint;
-    final iosEnable = isNfcScanUseDialog &&
-        (next?.type == MControlPointType.nfc ||
-            nextPlan?.type == MControlPointType.nfc);
-
-    return (instance.model.isInPlanControlPointArea ||
-            instance.model.isInWantControlPointArea ||
-            iosEnable) &&
-        isShowCheckCPButton;
-  }
-  /// 下个点方向弧度
-  double? get nextCPRadians {
-    final p0 = instance.model.myPosition;
-    final p1 = instance.model.nextPlanPoint?.position;
-
-    if(p0 == null || p1 == null){
-      return null;
-    }
-    return instance.compassRadiansFused.value + p0.directionTo(p1);
-  }
-  void showMyLocation() {
-    if (isEnableUserLocation) {
-      final p = instance.model.myPositionOnMap;
-      if (p != null) {
-        final dst = mapRotateCenter.value;
-        moveOnMapPointToScreen(p, dst);
-      }
-    }
-  }
-
-  void setRotateCenterToScreenCenter() {
-    final size = mapWidgetSize.value;
-    if (size != null) {
-      final screenCenter = Offset(size.width / 2, size.height / 2);
-      mapRotateCenter.value = screenCenter;
-    }
-  }
-
-  void setRotateCenterToCompassCenter() {
-    mapRotateCenter.value = compassCenter;
-  }
-
-  @override
-  void onMapSizeChange(Size size) {
-    super.onMapSizeChange(size);
-    flushRotateCenter();
-    if (!isLockScreenCenterToMyPositionSystem) {
-      showNextPoint();
-    }
-
-
-    mapDoScale(2.3);
-  }
-
-  void flushRotateCenter() {
-    if (isMapRotateAtCompassCenter.value) {
-      setRotateCenterToCompassCenter();
-    } else {
-      setRotateCenterToScreenCenter();
-    }
-    if (isLockScreenCenterToMyPositionSystem) {
-      showMyLocation();
-    }
-  }
-
-  void mapModeSwitch() {
-    switch (mapRotationMode.value) {
-      case MapMode.original:
-        _setMapMode(MapMode.compass);
-        break;
-      case MapMode.compass:
-        _setMapMode(MapMode.original);
-        break;
-    }
-  }
-
-  void _setMapMode(MapMode mode) {
-    resetMatrix();
-    mapRotationMode.value = mode;
-  }
-
-  @override
-  bool get isEnableUserTouchRotation {
-    if (mapRotationMode.value == MapMode.compass) {
-      return false;
-    }
-    return true;
-  }
-
-  @override
-  bool get isEnableUserTouchTranslation {
-    if (isLockScreenCenterToMyPositionSystem) {
-      return false;
-    }
-    return true;
-  }
-
-  void showNextPoint() {
-    final next = instance.model.nextPlanPoint;
-    if (next != null) {
-      moveOnMapPointToScreen(next.onMap, mapRotateCenter.value);
-    }
-  }
-
-  Future<void> toSettings() async {
-    await Get.to(() => const GameSettingsView(isInGame: true));
-  }
-  Future<void> showCheckedCP() async {
-    showCheckedPoints(instance.checkedPointsHistory);
-  }
-
-  Future<void> onSwitchCompassSize() async {
-    _compassSizeIndex++;
-    if (_compassSizeIndex >= _compassSizeList.length) {
-      _compassSizeIndex = 0;
-    }
-
-    compassDiameter.value = _compassSizeList[_compassSizeIndex];
-    flushRotateCenter();
-  }
-
-  void showCompassSwitch() {
-    isShowCompass.value = !isShowCompass.value;
-  }
-
-  void forceExit() {
-    instance.gameGiveUp();
-  }
-
-  _playCheckSound(MControlPoint cp) async {
-    if (cp.isFinish) {
-      return;
-    }
-    await Future.delayed(200.milliseconds);
-    var src = cp.isSuccess ? 'assets/sound/ok.wav' : 'assets/sound/fail.wav';
-    if (!cp.isSuccess && cp.isPlan) {
-      src = Assets.soundPlanOk;
-    }
-    if (isClosed) {
-      return;
-    }
-    await _app.soundPlayAsset(src);
-  }
-
-  _closeExistDialog() {
-    if (Get.isOverlaysOpen) {
-      Get.back();
-    }
-  }
-
-  void dialogRoutePlanning(){
-
-    Get.dialog(Center(
-        child: Obx((){
-          final model = instance.model;
-
-          return RoutePlanning(
-              want: model.controlPointWantSequence,
-              nextPlanPoint: model.nextPlanPoint,
-              nextWantPoint: model.nextWantPoint,
-              onClick: (point){
-                model.nextPlanPoint=point;
-              });
-        }) ),
-    );
-  }
-  _onChecked(MControlPoint cp) {
-    _closeExistDialog();
-
-    final isEnablePunchErrorPrompt = _app.userProfile.gameSettingsPunchErrorPrompt.value;
-
-
-    final next = instance.model.nextWantPoint;
-    _playCheckSound(cp);
-    if (cp.isSuccess) {
-      if (cp.isStart) {
-        Get.dialog(DialogCheckText(
-          text: '开始',
-          color: Colors.white,
-          autoPlayAfter: 200.milliseconds,
-        ));
-      } else {
-        showDialogCheckRich(cp, instance.model.gameQuestionShowDuration)
-            .then((value) {
-          instance.save();
-        });
-      }
-    } else {
-      if (cp.isPlan) {
-        Get.dialog(const DialogCheckText(
-          text: '已打点',
-          color: Color(0xffff870d),
-        ));
-      } else if (next != null) {
-        if(isEnablePunchErrorPrompt){
-          dialogCPOrderErr(next);
-        }
-
-      } else {
-        if(isEnablePunchErrorPrompt) {
-          Get.dialog(
-              const DialogCheckText(text: '打点错误', color: Colors.red));
-        }
-      }
-    }
-  }
-
-  _onProjectPoint(MControlPointInProject point) {
-    _closeExistDialog();
-    _playCheckSound(MControlPoint()..isSuccess = false);
-
-    Get.dialog(dialogTitle('非线路检查点', Colors.red, const Text('请检查地图线路'),
-        offAfter: 3.seconds));
-  }
-
-  _onNoPoint() {
-    _closeExistDialog();
-    _playCheckSound(MControlPoint()..isSuccess = false);
-
-    Get.dialog(dialogTitle('打点错误', Colors.red, const Text('不是检查点'),
-        offAfter: 3.seconds));
-  }
-
-  Future<void> _onIosNfcStart() async {
-    if (!(await App.to.isNfcAvailable)) {
-      Get.showSnackbar(const GetSnackBar(
-        message: 'NFC不可用',
-      ));
-      return;
-    }
-
-    NfcManager.instance.startSession(
-      alertMessage: '请靠近打卡点',
-      onDiscovered: (tag) async {
-        try {
-          await _onNfcDiscovered(tag);
-          await NfcManager.instance.stopSession(alertMessage: '打卡成功');
-        } catch (e) {
-          await NfcManager.instance.stopSession(errorMessage: '$e');
-        }
-      },
-    );
-  }
-
-  Future<void> onCheckControlPoint() async {
-    final next = instance.model.nextWantPoint;
-    if (next != null) {
-      switch (next.type) {
-        case MControlPointType.nfc:
-          await _onIosNfcStart();
-          break;
-        case MControlPointType.gps:
-          await instance.checkPointGps(_onChecked, _onConfirmFinish);
-          break;
-      }
-    }
-  }
-
-  void updateCompassRotateMap(double radians) {
-    if (mapRotationMode.value == MapMode.compass) {
-      setRotate(radians);
-    }
-  }
-
-  void _registerNFC() {
-    if (!isNfcScanUseDialog) {
-      NfcManager.instance.startSession(
-          onDiscovered: _onNfcDiscovered, alertMessage: '保持NFC靠近');
-      info('Nfc开始扫描');
-    }
-  }
-
-  Future<void> _onNfcDiscovered(NfcTag tag) async {
-    info("NFC: \n ${tag.data}");
-    String identifier = "";
-
-    if (Platform.isAndroid) {
-      identifier = (NfcA.from(tag)?.identifier ??
-              NfcB.from(tag)?.identifier ??
-              NfcF.from(tag)?.identifier ??
-              NfcV.from(tag)?.identifier ??
-              Uint8List(0))
-          .toHexString();
-    }
-    if (Platform.isIOS) {
-      identifier = (Iso15693.from(tag)?.identifier ??
-              Iso7816.from(tag)?.identifier ??
-              MiFare.from(tag)?.identifier ??
-              Uint8List(0))
-          .toHexString();
-    }
-
-    info('Id: $identifier');
-
-    instance.checkPointNFC(
-        identifier, _onChecked, _onConfirmFinish, _onProjectPoint, _onNoPoint);
-  }
-
-  Future<bool> _onConfirmFinish() async {
-    return true;
-    // return await dialogAskConfirmFinish();
-  }
-
-  void _onPositionUpdate(List<Offset> offset) {
-    if (offset.isNotEmpty) {
-      final p = offset.last;
-
-      if (isLockScreenCenterToMyPositionSystem) {
-        showMyLocation();
-      }
-    }
-  }
-  Future<void> _workPlayDistanceSound()async{
-    while(!isClosed){
-      final model = instance.model;
-      final distance = model.nextPlanCPDistance;
-      if(distance != null && model.endAt==null){
-
-        var d = 5200.milliseconds;
-        String? src = 'assets/sound/beep.wav';
-        if(distance < 30.meter){
-          d = 1200.milliseconds;
-        }
-
-        if(distance < 10.meter){
-          d = 700.milliseconds;
-        }
-
-
-        if((model.isInPlanControlPointArea && model.nextPlanPoint?.type == MControlPointType.gps)
-            || (model.isInWantControlPointArea&&  model.nextWantPoint?.type == MControlPointType.gps)){
-
-          d = 3400.milliseconds;
-          src = 'assets/sound/punch_alarm.mp3';
-        }
-
-
-        await _app.soundPlayAsset(src);
-        await Future.delayed(d);
-      }else{
-        await Future.delayed(500.milliseconds);
-      }
-    }
-  }
-
-
-
-  @override
-  void onReady() {
-    super.onReady();
-    _updateSettings();
-    _listenSettings();
-    setIsBrightnessMax(isBrightnessMax);
-    _setMapMode(MapMode.compass);
-    _workPlayDistanceSound();
-
-    state.bindStream(instance.stateStream);
-    settlementTip.bindStream(instance.errorMsg.stream);
-    _subscriptions.add(instance.stateStream.listen((state) {
-      debug('游戏状态:$state');
-      if (state == GameInstanceState.closed) {
-        dialogFinishResult(instance.finishData);
-      }
-    }));
-
-    _subscriptions.add(instance.compassRadiansFused.listen((r) {
-      updateCompassRotateMap(r);
-    }));
-    _subscriptions
-        .add(instance.model.myPositionOnMapHistory.listen(_onPositionUpdate));
-
-    _registerNFC();
-
-    gameCompassController.duration.bindStream(instance.model.duration.stream);
-    gameCompassController.compassRadians.bindStream(instance.compassRadiansSrc.stream);
-    _subscriptions.add(instance.compassRadiansSrc.listen((p) {
-      final p0 = instance.model.myPosition;
-      final p1 = instance.model.nextPlanPoint?.position;
-
-      if(p0 == null || p1 == null){
-        return;
-      }
-      gameCompassController.nextPointRadians.value=p + p0.directionTo(p1);
-    }));
-    gameCompassController.heartRatePercent.bindStream(instance.model.heartRatePercent.stream);
-    gameCompassController.heartRate.bindStream(instance.model.heartRate.stream);
-    gameCompassController.stepCount.bindStream(instance.model.stepCount.stream);
-    gameCompassController.kCal.bindStream(instance.model.kCal.stream);
-    gameCompassController.ck.bindStream(instance.model.ck.stream);
-    gameCompassController.ei.bindStream(instance.model.ei.stream);
-  }
-
-  @override
-  void onClose() {
-    super.onClose();
-    for (final one in _subscriptions) {
-      one.cancel();
-    }
-    if (!isNfcScanUseDialog) {
-      NfcManager.instance.stopSession();
-    }
-    cancelListen?.call();
-    state.close();
-    settlementTip.close();
-  }
-  final gameCompassController = GameCompassController();
-  final GameInstanceStd instance;
-  final _app = App.to;
-
-  UserProfile get _profile => _app.userProfile;
-  final _subscriptions = <StreamSubscription>[];
-
-  @override
-  GameMap? get gameMap => instance.gameMapData;
-  final isShowTrace = true.obs;
-  final isMapRotateAtCompassCenter = false.obs;
-
-  static const bottomBarHeight = 120.0;
-  final isSimpleDashboard = true.obs;
-  final isEnableRoutePreview = true.obs;
-  final isEnableUserLocationState = true.obs;
-  final gameUIMode = GameUIMode.electronicMap.obs;
-  void Function()? cancelListen;
-  var isLockScreenCenterToMyPosition = false;
-
-  /// 用户设置是否锁定旋转中心
-  bool get isLockScreenCenterToMyPositionSystem =>
-      isLockScreenCenterToMyPosition && isEnableUserLocation;
-
-  bool get isEnableUserLocation => _profile.gameSettingsShowMyLocation.value;
-
-  set isEnableUserLocation(v) {
-    _profile.gameSettingsShowMyLocation.value = v;
-  }
-
-  final compassDiameter = 160.0.obs;
-
-  Offset get compassCenter => Offset(App.to.screenSize.width / 2,
-      App.to.screenSize.height - bottomBarHeight - compassDiameter / 2);
-  final mapRotationMode = MapMode.compass.obs;
-  final state = GameInstanceState.uninitialized.obs;
-
-  MNetImage get legend =>
-      instance.model.gameSrcState.value.pbGameData.legendImage.toModel();
-
-  bool get isBrightnessMax =>
-      App.to.userProfile.isEnableInGameBrightnessMax.val;
-
-  Future<void> setIsBrightnessMax(bool v) async {
-    App.to.userProfile.isEnableInGameBrightnessMax.val = v;
-    if (v) {
-      await ScreenBrightness().setScreenBrightness(1);
-    } else {
-      await ScreenBrightness().resetScreenBrightness();
-    }
-  }
-
-  final compassLevel = Compass2.levelMin.obs;
-  var _compassSizeIndex = 0;
-  final _compassSizeList = <double>[160.0, 200, 240, 280];
-  final isShowCompass = true.obs;
-  final isNoMapRulerScaleMode = false.obs;
-  /// 是否显示下一个点的方向
-  final isShowNextCPRadians = true.obs;
-  final isShowRuler = false.obs;
-
-  bool get isCheckCPButtonWarn =>
-      instance.model.isInWantControlPointArea && isCheckCPButtonEnable;
-  final settlementTip = '正在计算,请稍后'.obs;
-
-  double get compassPlantRadian {
-    if (mapRotationMode.value == MapMode.compass) {
-      return instance.compassRadiansFused.value;
-    }
-
-    final ogRm = mapTransformMatrix.value.clone();
-    double radian = MatrixGestureDetector.decomposeToValues(ogRm).rotation;
-    return radian;
-  }
-
-  int get compassShowDegrees {
-    var d1 = -(compassPlantRadian - instance.compassRadiansFused.value);
-    if (mapRotationMode.value == MapMode.compass) {
-      d1 = -compassPlantRadian;
-    }
-    var d = d1 * 180 ~/ pi;
-    while (d < 0) {
-      d += 360;
-    }
-    while (d > 360) {
-      d -= 360;
-    }
-    return d;
-  }
-  /// 地图比例尺 1:[userSetMapScale]
-  final Rx<double?> userSetMapScale = Rx(null);
-
-  sensor.Orientation get orientation => instance.orientation.value;
-
-  bool get isPhoneHorizontal {
-    final x = vec.degrees(orientation.x);
-    final y = vec.degrees(orientation.y);
-    if (x.abs() > 30 || y.abs() > 30) {
-      return false;
-    } else {
-      return true;
-    }
-  }
-
-  bool get isShowPhoneHorizontalWarn =>
-      (!isPhoneHorizontal) && (!instance.isPersonMoving);
-
-  bool get isOutBoundary {
-    final p = instance.model.myPositionOnMap;
-
-    if (p != null) {
-      final mapWidth = instance.gameMapData.width;
-      final mapHeight = instance.gameMapData.height;
-
-      if (p.dx <= 0 || p.dx >= mapWidth || p.dy <= 0 || p.dy >= mapHeight) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  bool get isShowOutBoundaryWarn =>
-      App.to.userProfile.gameSettingsBoundaryWarn.value && isOutBoundary;
-}

+ 0 - 51
lib/view/ingame/game_std/game_std_view.dart

@@ -1,51 +0,0 @@
-import 'package:trackoffical_app/service/game/game_instance.dart';
-import 'package:trackoffical_app/service/game/game_instance_std/game_instance_std.dart';
-import 'package:trackoffical_app/service/user_profile.dart';
-import 'package:trackoffical_app/view/ingame/game_std/game_std_view_no_map.dart';
-import 'package:trackoffical_app/view/ingame/game_std/game_std_view_paper_map.dart';
-import 'package:trackoffical_app/view/ingame/instance_view.dart';
-import 'game_std_view_emap.dart';
-import 'settlement_view.dart';
-import '../in_game_loading2.dart';
-import 'game_std_controller.dart';
-
-
-class GameStdView extends GetView<LayerController>{
-  const GameStdView({super.key});
-
-  static void toGameStdView(GameInstanceStd instance){
-    Get.offAll(()=>const GameStdView(),
-      binding: BindingsBuilder(() {
-        Get.lazyPut<LayerController>(() => GameStdController(instance));
-      })
-    );
-  }
-
-  GameStdController get c => controller as GameStdController;
-
-  @override
-  Widget build(BuildContext context) {
-    return InstanceView(instance: c.instance,
-        closingView: const SettlementView(),
-        child: const GameStdViewNoMap()
-    );
-  }
-
-  /*@override
-  Widget build(BuildContext context) {
-    return InstanceView(instance: c.instance,
-        closingView: const SettlementView(),
-        child: Obx((){
-          switch(c.gameUIMode.value){
-            case GameUIMode.electronicMap:
-              return const GameStdViewEMap();
-            case GameUIMode.noMap:
-              return const GameStdViewNoMap();
-            case GameUIMode.paperMap:
-              return const GameStdViewPaperMap();
-          }
-        })
-    );
-  }*/
-
-}

+ 0 - 97
lib/view/ingame/game_std/game_std_view_compass.dart

@@ -1,97 +0,0 @@
-import 'package:trackoffical_app/view/ingame/game_std/utils.dart';
-import '../../../model/game_person_data.dart';
-import 'button_punch.dart';
-import '../game_compass/game_compass_button.dart';
-import '../game_compass/game_compass_top4_data.dart';
-import 'game_std_controller.dart';
-import 'info_view.dart';
-export 'game_std_controller.dart';
-
-abstract class GameStdViewCompass extends LayerView<GameStdController> {
-  const GameStdViewCompass({super.key});
-
-  GamePersonData get model => viewModel.instance.model;
-
-
-  List<GameCompassTop4Data> top4Data() {
-    return [
-
-      GameCompassTop4Data(
-          title: '目标',
-          child: Obx(() => model.nextPlanPoint.display(
-              textStyle: const TextStyle(
-                  fontSize: 21.78, fontWeight: FontWeight.w500))) ),
-      GameCompassTop4Data(
-          title: '里程',
-          child: Padding(
-              padding: const EdgeInsets.only(left: 16, right: 16),
-              child: Obx(()=>model.widgetDistance(
-                  withTrip: !viewModel.isSimpleDashboard.value))) ),
-      GameCompassTop4Data(
-          title: '点距',
-          child: Obx(()=>_nextCPDistance())),
-      GameCompassTop4Data(
-          title: '配速',
-          child: Padding(
-              padding: const EdgeInsets.only(left: 16, right: 16),
-              child: Obx(()=>model.widgetPace(
-                  withTrip: !viewModel.isSimpleDashboard.value)))),
-    ];
-  }
-
-  Widget _nextCPDistance() {
-
-    var unit = ' km';
-    var value = '--';
-    final dis = model.nextPlanCPDistanceKmShow;
-    if(dis!= null){
-      (value, unit) = dis.toStringValueAndUnit();
-    }
-    return RichText(
-        text: TextSpan(
-            text: value,
-            style:
-            const TextStyle(fontSize: 28.31, fontWeight: FontWeight.w500),
-            children: [
-              TextSpan(
-                  text: unit,
-                  style:
-                  const TextStyle(fontSize: 13.07, fontWeight: FontWeight.w500))
-            ]));
-  }
-
-  List<Widget>  topButtons(){
-    return [
-      buttonInfo(onPressed: () => Get.to(() => InfoView())),
-      buttonCheckedCP(onPressed: viewModel.showCheckedCP),
-      buttonBrightness(onPressed: _onBrightness),
-      buttonSettings(onPressed: viewModel.toSettings),
-      buttonExit(onPressed: ()=>onButtonExit(viewModel)),
-    ];
-  }
-  void _onBrightness()async{
-    await viewModel.setIsBrightnessMax(!viewModel.isBrightnessMax);
-  }
-  Widget process() {
-    return Obx(() => Text('${model.checkedCount}/${model.validCPAllNum}',
-        maxLines: 1,
-        style: const TextStyle(
-          fontSize: 32,
-        )));
-  }
-
-  Widget punchButton() {
-    return Obx(
-          () => SizedBox(
-        width: 56,
-        height: 56,
-        child: ButtonPunch(
-          onPressed: viewModel.isCheckCPButtonEnable
-              ? viewModel.onCheckControlPoint
-              : null,
-          isWarn: viewModel.isCheckCPButtonWarn,
-        ),
-      ),
-    );
-  }
-}

+ 0 - 69
lib/view/ingame/game_std/game_std_view_emap.dart

@@ -1,69 +0,0 @@
-import 'layer_cp_start_bubble.dart';
-import 'layer_map_ruler.dart';
-import 'layer_warn.dart';
-import 'layer_compass.dart';
-import 'layer_cp_touch.dart';
-import 'layer_location.dart';
-import '../layer/layer_cp.dart';
-import 'layer_front_ui.dart';
-import '../layer/layer_map.dart';
-import '../layer/layer_map_touch.dart';
-import '../layer/layer_trace.dart';
-import 'game_std_controller.dart';
-
-class GameStdViewEMap extends LayerView<GameStdController>{
-  const GameStdViewEMap({super.key});
-
-  @override
-  Widget build(BuildContext context) {
-    return Obx((){
-      final children = <Widget>[
-        const SizedBox(width: double.infinity, height: double.infinity),
-      ];
-
-      if(viewModel.isWidgetInit){
-        children.add(const LayerMap());
-        if(viewModel.isShowTrace.value && viewModel.isEnableUserLocationState.value){
-          children.add(LayerTrace(
-              onMapTrace: viewModel.instance.myTrace,
-              color: Colors.red));
-        }
-
-        children.addAll([
-          LayerCP(
-            isHideRouteBeforeStart: !viewModel.isEnableRoutePreview.value,
-            wantList: viewModel.instance.model.controlPointWantSequence,
-            nextPlanCPIndex: viewModel.instance.model.nextPlanPointIndex.value,
-            numRadians: viewModel.compassPlantRadian,
-          ),
-          const LayerCPStartBubble(),
-        ]);
-
-        if(viewModel.isEnableUserLocationState.value){
-          children.add(const LayerLocation());
-        }
-
-        children.addAll([
-          const LayerMapRuler(),
-          const LayerCompass(),
-          const LayerWarn(),
-          const LayerMapTouch(),
-          const LayerCPTouch(),
-          const LayerFrontUI(),
-        ]);
-      }
-
-
-
-      return Scaffold(
-        backgroundColor: const Color(0xffd6d6d6),
-        body: Stack(
-            key: viewModel.mapWidgetKey,
-            alignment: Alignment.topLeft,
-            children: children
-        ),
-      );
-    });
-  }
-
-}

+ 0 - 18
lib/view/ingame/game_std/game_std_view_no_map.dart

@@ -1,18 +0,0 @@
-import '../game_compass/game_compass_base.dart';
-import 'game_std_view_compass.dart';
-
-class GameStdViewNoMap extends  GameStdViewCompass{
-  const GameStdViewNoMap({super.key});
-  @override
-  Widget build(BuildContext context) {
-    return GameCompassBase(
-        controller: viewModel.gameCompassController,
-        top4data: top4Data(),
-        topButtons: topButtons(),
-        process: process(),
-        isShowNextPointer: true,
-        isEnableRuler: false,
-        bottomCenterButton: punchButton());
-  }
-}
-

+ 0 - 19
lib/view/ingame/game_std/game_std_view_paper_map.dart

@@ -1,19 +0,0 @@
-import 'package:trackoffical_app/model/game_person_data.dart';
-import 'package:trackoffical_app/view/ingame/game_compass/game_compass_base.dart';
-import 'game_std_view_compass.dart';
-
-class GameStdViewPaperMap extends GameStdViewCompass {
-  const GameStdViewPaperMap({super.key});
-
-  @override
-  Widget build(BuildContext context) {
-    return GameCompassBase(
-        controller: viewModel.gameCompassController,
-        top4data: top4Data(),
-        topButtons: topButtons(),
-        process: process(),
-        isShowNextPointer: false,
-        isEnableRuler: true,
-        bottomCenterButton: punchButton());
-  }
-}

+ 0 - 59
lib/view/ingame/game_std/info_view.dart

@@ -1,59 +0,0 @@
-import '../../../widget/app_net_image.dart';
-import 'game_std_controller.dart';
-import 'package:webview_flutter/webview_flutter.dart';
-
-class InfoView extends LayerView<GameStdController>{
-  late final WebViewController wc;
-
-  InfoView({super.key}){
-
-    wc = WebViewController()
-      ..setJavaScriptMode(JavaScriptMode.unrestricted)
-      ..setBackgroundColor(const Color(0x00000000))
-      ..setNavigationDelegate(
-        NavigationDelegate(
-          onProgress: (int progress) {
-            // Update loading bar.
-          },
-          onPageStarted: (String url) {},
-          onPageFinished: (String url) {},
-          onWebResourceError: (WebResourceError error) {},
-          // onNavigationRequest: (NavigationRequest request) {
-          //   if (request.url.startsWith('https://www.youtube.com/')) {
-          //     return NavigationDecision.prevent;
-          //   }
-          //   return NavigationDecision.navigate;
-          // },
-        ),
-      )
-      ..loadRequest(Uri.parse('https://www.beswell.com/info/info.html'));
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    return DefaultTabController(
-      initialIndex: 0,
-      length: 2,
-      child: Scaffold(
-        appBar: AppBar(
-          title: const Text(''),
-          bottom:const  TabBar(tabs: [
-            Tab(text: '帮助'),
-            Tab(text: '图例')
-          ]),
-        ),
-        body: TabBarView(
-          physics: const NeverScrollableScrollPhysics(),
-          children: [
-            WebViewWidget(controller: wc),
-            AppNetImage(
-              netImage: viewModel.legend,
-              fit: BoxFit.contain,
-            )
-          ],
-        )    ,
-      )
-    );
-  }
-
-}

+ 0 - 33
lib/view/ingame/game_std/layer_compass.dart

@@ -1,33 +0,0 @@
-import '../../../widget/compass2.dart';
-import 'game_std_controller.dart';
-
-class LayerCompass extends LayerView<GameStdController> {
-  const LayerCompass({super.key});
-
-  @override
-  Widget build(BuildContext context) {
-
-    return Obx(() {
-      if (viewModel.isShowCompass.value) {
-        final diameter = viewModel.compassDiameter.value;
-        final left = (context.width - diameter) / 2;
-
-        return Positioned(
-            left: left,
-            top: viewModel.compassCenter.dy - diameter / 2,
-            child: Compass2(
-              compassRadians: viewModel.instance.compassRadiansFused.value,
-              mapNorthRadians: viewModel.compassPlantRadian,
-              nextPointRadians: viewModel.isShowNextCPRadians.value
-                  ? viewModel.compassPlantRadian
-                  : null,
-              level: viewModel.compassLevel.value,
-              showDegrees: viewModel.compassShowDegrees,
-              diameter: diameter,
-            ));
-      } else {
-        return Container();
-      }
-    });
-  }
-}

+ 0 - 49
lib/view/ingame/game_std/layer_cp_start_bubble.dart

@@ -1,49 +0,0 @@
-import 'dart:math';
-
-import 'package:bubble/bubble.dart';
-import 'package:trackoffical_app/screen.dart';
-
-import 'game_std_controller.dart';
-
-class LayerCPStartBubble extends LayerView<GameStdController> {
-  const LayerCPStartBubble({super.key});
-
-
-
-  @override
-  Widget build(BuildContext context) {
-    return Obx(() {
-      final model =  viewModel.instance.model;
-
-      var points = model.controlPointWantSequence;
-
-      if (model.startAt != null || points.isEmpty) {
-        return const SizedBox();
-      }
-      final start = points[0];
-
-      var xy = viewModel
-          .mapOffsetToScreen(Offset(start.onMap.dx, start.onMap.dy));
-
-      var x = xy.dx;
-      var y = xy.dy;
-      var h0 = viewModel
-          .mapOffsetToScreen(const Offset(0, 0));
-      var h1 = viewModel
-          .mapOffsetToScreen(const Offset(0, 60));
-      final dx = h1.dx - h0.dx;
-      final dy = h1.dy - h0.dy;
-      var h = sqrt(dx * dx + dy * dy);
-
-      return Positioned(
-        top: y,
-        left: x + h + 1.0.wp,
-        child: Bubble(
-          nip: BubbleNip.leftTop,
-          alignment: Alignment.topRight,
-          child: const Text('打开始点后计时', style: TextStyle(color: Colors.red)),
-        ),
-      );
-    });
-  }
-}

+ 0 - 45
lib/view/ingame/game_std/layer_cp_touch.dart

@@ -1,45 +0,0 @@
-import 'package:get/get.dart';
-import 'package:flutter/material.dart';
-import 'package:trackoffical_app/service/game/game.dart';
-import 'package:trackoffical_app/service/game/game_model.dart';
-import 'package:trackoffical_app/view/ingame/game_std/game_std_controller.dart';
-import 'package:transparent_pointer/transparent_pointer.dart';
-
-class LayerCPTouch extends LayerView<GameStdController> {
-  const LayerCPTouch({super.key});
-
-  @override
-  Widget build(BuildContext context) {
-    return Obx(() {
-      final children = <Widget>[];
-      final wants = viewModel.instance.model.controlPointWantSequence;
-      const size = 40.0;
-
-      for (var i = 0; i < wants.length; i++) {
-        final one = wants[i];
-        final offset = viewModel.mapOffsetToScreen(one.onMap);
-        var x = offset.dx;
-        var y = offset.dy;
-
-        children.add(Positioned(
-            left: x - size / 2,
-            top: y - size / 2,
-            child:TransparentPointer(
-                child:GestureDetector(
-                  onDoubleTap: () {
-                    viewModel.instance.model.nextPlanPoint = one;
-                  },
-                  child: Container(
-                    height: size,
-                    width: size,
-                    color: Colors.red.withAlpha(0),
-                  ),
-                ))) );
-      }
-
-      return Stack(
-        children: children,
-      );
-    });
-  }
-}

+ 0 - 42
lib/view/ingame/game_std/layer_front_ui.dart

@@ -1,42 +0,0 @@
-import 'game_std_controller.dart';
-import 'layer_front_ui_bottom_bar.dart';
-import 'layer_front_ui_button_bar.dart';
-
-class LayerFrontUI extends GetView<LayerController> {
-  const LayerFrontUI({super.key});
-
-  GameStdController get c => controller as GameStdController;
-
-  @override
-  Widget build(BuildContext context) {
-    return Column(
-      children: [
-        Container(
-          width: context.width,
-          height: context.mediaQueryPadding.top,
-          decoration: BoxDecoration(color: Colors.grey.withAlpha(150)),
-        ),
-        // _TopBar(),
-        Expanded(
-            child: Container(
-                padding: const EdgeInsets.only(top: 12),
-                width: double.infinity,
-                child: Stack(
-                  alignment: AlignmentDirectional.center,
-                  children: [
-                    Obx(() {
-
-                      return LayerButtonBar(
-                        isShowCheckCPButton: c.isShowCheckCPButton,
-                        isCheckCPButtonEnable:
-                                c.isCheckCPButtonEnable,
-                      );
-                    }),
-                    // _PhoneHorizontalWarn(),
-                  ],
-                ))),
-        const LayerBottomBar(),
-      ],
-    );
-  }
-}

+ 0 - 363
lib/view/ingame/game_std/layer_front_ui_bottom_bar.dart

@@ -1,363 +0,0 @@
-import 'package:trackoffical_app/model/game_person_data.dart';
-import 'package:trackoffical_app/styles/theme.dart';
-import 'package:trackoffical_app/utils.dart';
-import 'utils.dart';
-import '../../../model/m_control_point.dart';
-import 'game_std_controller.dart';
-
-
-
-class LayerBottomBar extends GetView<LayerController> {
-  const LayerBottomBar({super.key});
-
-  GameStdController get c => controller as GameStdController;
-  GamePersonData get _model =>c.instance.model;
-
-  @override
-  Widget build(BuildContext context) {
-    return Obx(() {
-      final duration = _model.duration.value.toAppString();
-      final next = _model.nextPlanPoint;
-      final hrp = _model.heartRatePercent.value.round();
-      var color = hrp.toHRPColor();
-      var cpChecked = _model.checkedCount;
-      final isSimpleDashboard =c.isSimpleDashboard.value;
-
-      return SizedBox(
-        height: GameStdController.bottomBarHeight,
-        width: context.width,
-        child: PageView(
-          scrollDirection: Axis.horizontal,
-          children: [
-            BottomBar1(
-                color: color,
-                duration: duration,
-                myPositionHistoryLenKm: _model.myPositionHistoryLen.value.km,
-                targetDistanceKm: _model.nextPlanCPDistanceKmShow?.km,
-                paceSecond: _model.paceSecondKm.value,
-                nextCp: next,
-                cpAll: _model.validCPAllNum,
-                cpChecked: cpChecked,
-                distance: _model.widgetDistance(fontSize: 21, withTrip: !isSimpleDashboard),
-                pace:  _model.widgetPace(fontSize: 21, withTrip: !isSimpleDashboard)),
-            BottomBar2(
-                color: color,
-                duration: duration,
-                cpAll: _model.validCPAllNum,
-                cpChecked: cpChecked,
-                hr: _model.heartRate.value,
-                hrp: hrp,
-                stepCount: _model.stepCount.value,
-                kCal: _model.kCal.value,
-                ck: _model.ck.value,
-                ei: _model.ei.value)
-          ],
-        )
-      ) ;
-    });
-  }
-}
-
-
-Widget wDuration(String duration) {
-  return Text(duration,
-      style: const TextStyle(fontSize: 20, fontFamily: 'sa-digital-number'));
-}
-
-
-
-Widget elemCp(MControlPoint? nextCp) {
-  Widget text;
-  const style = TextStyle(fontSize: 26, fontWeight: FontWeight.w700);
-  if (nextCp != null) {
-    text = nextCp.display(textStyle: style);
-    if (nextCp.areaId.isNotEmpty && nextCp.type == MControlPointType.nfc) {
-      text = Row(
-        mainAxisSize: MainAxisSize.min,
-        children: [
-          text,
-          Text(
-            ' (${nextCp.areaId})',
-            style: style,
-          )
-        ],
-      );
-    }
-  } else {
-    text = const Text('--', style: style, maxLines: 1);
-  }
-
-  return text;
-}
-
-Widget wKm(double? km, double fontSize, {FontWeight? fontWeight}) {
-  var unit = ' km';
-  var value = '--';
-
-  if(km != null){
-    var i = km;
-    if (km < 1) {
-      unit = ' m';
-      i *= 1000;
-    }
-    value = i.round().toString();
-  }
-
-  return RichText(
-      text: TextSpan(
-          text: value,
-          style: TextStyle(fontSize: fontSize, fontWeight: fontWeight?? FontWeight.w500),
-          children: [
-            TextSpan(
-              text: unit,
-              style: TextStyle(fontSize: fontSize* 0.5, fontWeight: FontWeight.w500))
-          ]
-      ));
-}
-
-class BottomBar1 extends StatelessWidget {
-  const BottomBar1({
-    super.key,
-    required this.color,
-    required this.duration,
-    required this.myPositionHistoryLenKm,
-    required this.targetDistanceKm,
-    required this.paceSecond,
-    required this.nextCp,
-    required this.cpAll,
-    required this.cpChecked,
-    required this.distance,
-    required this.pace,
-  });
-
-  final Color color;
-  final MControlPoint? nextCp;
-  final String duration;
-  final int cpAll;
-  final int cpChecked;
-  final double myPositionHistoryLenKm;
-  final double? targetDistanceKm;
-  final Duration paceSecond;
-  final Widget distance;
-  final Widget pace;
-
-  @override
-  Widget build(BuildContext context) {
-
-    return Stack(children: [
-      _BottomBarContainer(
-        color: color,
-        children: [
-          elemCp(nextCp),
-          wDuration(duration),
-          getElemDistance(),
-          wKm(targetDistanceKm, 26, fontWeight: FontWeight.w700),
-          Text('$cpChecked/$cpAll', style: const TextStyle(fontSize: 32)),
-          getElemPace()
-        ],
-      ),
-
-      Positioned(
-        left: 0,
-          top: 0,
-          child: getSmallTitle('目标')
-      ),
-      Positioned(
-          right: 0,
-          top: 0,
-          child: getSmallTitle('里程')
-      ),
-      Positioned(
-          left: 0,
-          bottom: 0,
-          child: getSmallTitle('点距')
-      ),
-      Positioned(
-          right: 0,
-          bottom: 0,
-          child: getSmallTitle('配速')
-      ),
-
-    ],) ;
-  }
-
-  Widget getElemDistance(){
-    return Padding(
-        padding: const EdgeInsets.only(left: 16, right: 16),
-        child: distance) ;
-  }
-  Widget getElemPace(){
-    return Padding(
-        padding: const EdgeInsets.only(left: 16, right: 16),
-        child: pace) ;
-  }
-}
-
-class BottomBar2 extends StatelessWidget {
-  const BottomBar2({
-    super.key,
-    required this.color,
-    required this.duration,
-    required this.cpAll,
-    required this.cpChecked,
-    required this.hr,
-    required this.hrp,
-    required this.stepCount,
-    required this.kCal,
-    required this.ck,
-    required this.ei,
-  });
-
-  final Color color;
-  final int hr;
-  final int hrp;
-  final String duration;
-  final int cpAll;
-  final int cpChecked;
-  final int stepCount;
-  final double kCal;
-  final double ck;
-  final double ei;
-
-  Widget wHrp() {
-    return Row(
-      mainAxisSize: MainAxisSize.min,
-      crossAxisAlignment: CrossAxisAlignment.start,
-      children: [
-        Text('$hrp',
-            style: const TextStyle(fontSize: 43, fontWeight: FontWeight.w700)),
-        const Text('%',
-            style: TextStyle(fontSize: 20, fontWeight: FontWeight.w700))
-      ],
-    );
-  }
-
-  Widget wHr() {
-    return Row(
-      mainAxisSize: MainAxisSize.min,
-      crossAxisAlignment: CrossAxisAlignment.start,
-      children: [
-        Text('$hr',
-            style: const TextStyle(fontSize: 43, fontWeight: FontWeight.w700)),
-        Padding(
-            padding: const EdgeInsets.only(top: 5),
-            child: Image.asset('assets/images/ic_heart.png', height: 14.4))
-      ],
-    );
-  }
-
-
-
-  @override
-  Widget build(BuildContext context) {
-    return _BottomBarContainer(
-      color: color,
-      children: [
-        wHrp(),
-        wDuration(duration),
-        wHr(),
-        Row(
-          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
-          children: [
-            wSport('$stepCount', 'assets/images/ic_step_count.png'),
-            const SizedBox(width: 12),
-            wSport(kCal.toStringAsFixed(1), 'assets/images/ic_kcal.png'),
-          ],
-        ),
-        Text('$cpChecked/$cpAll', style: const TextStyle(fontSize: 32)),
-        Row(
-          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
-          children: [
-            wSport(ck.toStringAsFixed(1), 'assets/images/ic_ck.png'),
-            const SizedBox(width: 12),
-            wSport(ei.round().toString(), 'assets/images/ic_ei.png'),
-          ],
-        ),
-      ],
-    );
-  }
-}
-
-class _BottomBarContainer extends StatelessWidget {
-  const _BottomBarContainer({required this.children, required this.color});
-
-  final List<Widget> children;
-  final Color color;
-
-  @override
-  Widget build(BuildContext context) {
-    return DefaultTextStyle(
-        style: const TextStyle(color: Colors.white),
-        child: Container(
-          width: context.width,
-          height: GameStdController.bottomBarHeight,
-          decoration: BoxDecoration(
-              color: color,
-              image: const DecorationImage(
-                  image: AssetImage('assets/images/bk_ingame_bottom_bar.png'))),
-          child: Column(
-            children: [
-              Expanded(
-                  child: Row(
-                children: [
-                  Expanded(flex: 4, child: Center(child: children[0])),
-                  Expanded(
-                    flex: 6,
-                    child: Center(child: children[1]),
-                  ),
-                  Expanded(flex: 4, child: Center(child: children[2])),
-                ],
-              )),
-              Expanded(
-                  child: Row(
-                children: [
-                  Expanded(flex: 4, child: Center(child: children[3])),
-                  Expanded(flex: 6, child: Center(child: children[4])),
-                  Expanded(flex: 4, child: Center(child: children[5])),
-                ],
-              )),
-            ],
-          ),
-        ));
-  }
-}
-
-void main() async {
-  final b1 = BottomBar1(
-    color: Colors.blue,
-    nextCp: MControlPoint()
-      ..isStart = true
-      ..areaId = 'A51',
-    targetDistanceKm: 1.234,
-    duration: "00:00:00",
-    cpAll: 18,
-    cpChecked: 7,
-    myPositionHistoryLenKm: 3.1,
-    paceSecond: 380.seconds,
-    distance: const SizedBox(),
-    pace: const SizedBox(),
-  );
-  final b2 = const BottomBar2(
-      color: Colors.blue,
-      duration: '00:00:00',
-      cpAll: 18,
-      cpChecked: 7,
-      hr: 123,
-      hrp: 80,
-      stepCount: 0,
-      kCal: 11231,
-      ck: 2344,
-      ei: 1231);
-
-  var bottom = b1;
-
-  runApp(GetMaterialApp(
-      theme: appThemeData(),
-      home: Scaffold(
-          body: Column(
-        children: [
-          Spacer(),
-          bottom,
-        ],
-      ))));
-}

+ 0 - 364
lib/view/ingame/game_std/layer_front_ui_button_bar.dart

@@ -1,364 +0,0 @@
-import 'package:trackoffical_app/generated/assets.dart';
-import 'package:trackoffical_app/model/game_person_data.dart';
-import 'package:trackoffical_app/screen.dart';
-import '../route_planning.dart';
-import 'button_punch.dart';
-import 'info_view.dart';
-import 'game_std_controller.dart';
-import 'utils.dart';
-import 'package:trackoffical_app/widget/compass2.dart';
-
-class LayerButtonBar extends StatefulWidget {
-  const LayerButtonBar({
-    super.key,
-    required this.isShowCheckCPButton,
-    required this.isCheckCPButtonEnable,
-  });
-
-  final bool isShowCheckCPButton;
-  final bool isCheckCPButtonEnable;
-
-  @override
-  State<StatefulWidget> createState() {
-    return _ButtonBarState();
-  }
-}
-
-enum _ExpandState {
-  hide,
-  middle,
-  all,
-}
-
-class _ButtonBarState extends State<LayerButtonBar> {
-  var state = _ExpandState.middle;
-  final controller = Get.find<LayerController>() as GameStdController;
-  GamePersonData get model => controller.instance.model;
-
-  @override
-  void initState() {
-    super.initState();
-
-  }
-
-  void onButtonMore() {
-    setState(() {
-      var i = state.index + 1;
-      if (i >= _ExpandState.values.length) {
-        i = 0;
-      }
-      state = _ExpandState.values[i];
-    });
-  }
-
-  void onLockScreenCenterToMyPosition() {
-    setState(() {
-      if (!controller.isLockScreenCenterToMyPositionSystem) {
-        controller.showMyLocation();
-      }
-
-      controller.isLockScreenCenterToMyPosition =
-          !controller.isLockScreenCenterToMyPosition;
-    });
-  }
-
-  void onRotateAt() {
-    setState(() {
-      controller.isMapRotateAtCompassCenter.value =
-          !controller.isMapRotateAtCompassCenter.value;
-    });
-
-    controller.flushRotateCenter();
-  }
-
-  void btnMore(List<Widget> col) {
-    var moreSrc = 'assets/images/btn_more1.png';
-    if (state == _ExpandState.middle) {
-      moreSrc = 'assets/images/btn_more2.png';
-    }
-    if (state == _ExpandState.all) {
-      moreSrc = 'assets/images/btn_more3.png';
-    }
-    col.add(_Button(icon: Image.asset(moreSrc), onPressed: onButtonMore));
-  }
-
-  // 屏幕移至站立点
-  void btnMyLocation(List<Widget> col) {
-    col.add(_Button(
-        icon: Image.asset('assets/images/btn_location.png'),
-        disableSrc: 'assets/images/btn_location_disable.png',
-        onPressed: controller.isEnableUserLocation ? controller.showMyLocation : null));
-  }
-
-  // 跳点
-  void btnSkipCp(List<Widget> col) {
-    // if (model.isAllowedPassCP) {
-    if (true) {
-      col.add(_Button(
-        icon: Image.asset('assets/images/btn_skip_cp.png'),
-        disableSrc: Assets.imagesBtnSkipCpDisable,
-      ));
-    }
-  }
-
-  // 路线规划
-  void btnPathPlanning(List<Widget> col) {
-    if (true) {
-      col.add(Obx(() => _Button(
-            icon: Image.asset('assets/images/btn_path_planning.png'),
-            disableSrc: Assets.imagesBtnPathPlanningDisable,
-            onPressed:
-                model.startAt != null ? controller.dialogRoutePlanning : null,
-          )));
-    }
-  }
-
-  // 地图旋转中心
-  void btnMapRotateCenter(List<Widget> col) {
-    var rotateSrc = 'assets/images/btn_rotate_at1.png';
-    if (controller.isMapRotateAtCompassCenter.value) {
-      rotateSrc = 'assets/images/btn_rotate_at2.png';
-    }
-    col.add(_Button(icon: Image.asset(rotateSrc), onPressed: onRotateAt));
-  }
-
-  // 锁定旋转中心
-  void btnLockRotateCenter(List<Widget> col) {
-
-      var src = 'assets/images/btn_unlock.png';
-      if (controller.isLockScreenCenterToMyPosition) {
-        src = 'assets/images/btn_locked.png';
-      }
-
-      col.add(_Button(
-          icon: Image.asset(src),
-          disableSrc: 'assets/images/btn_unlock_disable.png',
-          onPressed: controller.isEnableUserLocation
-              ? onLockScreenCenterToMyPosition
-              : null));
-
-  }
-
-  onMapModeSwitch() {
-    controller.mapModeSwitch();
-    controller.showNextPoint();
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    final col1 = <Widget>[];
-
-    btnMore(col1);
-
-    if (state == _ExpandState.middle || state == _ExpandState.all) {
-      // 标定地图方式
-      col1.add(_Button(
-          icon: Image.asset('assets/images/btn_map_rotate.png'),
-          onPressed: onMapModeSwitch));
-      btnMyLocation(col1);
-      btnLockRotateCenter(col1);
-      col1.addAll([
-        // 行动轨迹
-        _Button(
-            icon: Image.asset('assets/images/btn_trajectory.png'),
-            disableSrc: 'assets/images/btn_trajectory_disable.png',
-            onPressed: controller.isEnableUserLocation
-                ? () => setState(() {
-              controller.isShowTrace.value =
-                          !controller.isShowTrace.value;
-                    })
-                : null,
-            isSelected: controller.isShowTrace.value),
-
-        // 亮度
-        _Button(
-          icon: Image.asset('assets/images/btn_brightness.png'),
-          onPressed: _onBrightness,
-          isSelected: controller.isBrightnessMax,
-        ),
-      ]);
-    }
-
-    final col2 = <Widget>[];
-    final col3 = <Widget>[];
-    if (state == _ExpandState.all) {
-      col2.addAll([
-        // 指北针大小
-        _Button(
-            icon: Image.asset('assets/images/btn_compass_size.png'),
-            onPressed: controller.onSwitchCompassSize),
-
-        // 指北针显示
-        _Button(
-          icon: Image.asset('assets/images/btn_compass.png'),
-          onPressed: () => setState(() {
-            controller.showCompassSwitch();
-          }),
-          isSelected: controller.isShowCompass.value,
-        ),
-        // 指南针样式
-        _Button(
-            icon: Image.asset('assets/images/btn_compass_level.png'),
-            onPressed: onClickCompassLevel),
-
-        // 是否显示下一点方向
-        _Button(
-          icon: Image.asset('assets/images/btn_next_cp.png'),
-          onPressed: () => setState(() {
-            controller.isShowNextCPRadians.value =
-                !controller.isShowNextCPRadians.value;
-          }),
-          isSelected: controller.isShowNextCPRadians.value,
-        ),
-      ]);
-
-      btnSkipCp(col2);
-
-      col2.add(_Button(
-          icon: Image.asset('assets/images/btn_past_cp.png'),
-          onPressed: controller.showCheckedCP
-          // showCheckedPoints
-      ));
-
-      col3.addAll([
-        // 图例
-        _Button(
-            icon: Image.asset('assets/images/btn_info.png'),
-            onPressed: _showInfo),
-        // 设置
-        _Button(
-            icon: Image.asset('assets/images/btn_settings.png'),
-            onPressed: _toSettings),
-
-        // 显示标尺
-        _Button(
-          icon: Image.asset('assets/images/btn_ruler.png'),
-          onPressed: () => setState(() {
-            controller.isShowRuler.value = !controller.isShowRuler.value;
-          }),
-          isSelected: controller.isShowRuler.value,
-        ),
-      ]);
-
-      btnMapRotateCenter(col3);
-      btnPathPlanning(col3);
-
-      // 退赛
-      col3.add(_Button(
-          icon: Image.asset('assets/images/btn_exit.png'),
-          onPressed: () => onButtonExit(controller)));
-    }
-
-    final children = <Widget>[
-      Row(
-        children: [
-          Column(
-            children: col1,
-          ),
-          const Spacer(),
-          Column(children: col2),
-          Column(children: col3)
-        ],
-      ),
-    ];
-    if (widget.isShowCheckCPButton) {
-      final color = widget.isCheckCPButtonEnable ? Colors.black : Colors.grey;
-
-      children.addAll([
-        const Spacer(),
-        Row(
-          children: [
-            const Spacer(),
-            ButtonPunch(
-              onPressed: widget.isCheckCPButtonEnable
-                  ? controller.onCheckControlPoint
-                  : null,
-              isWarn: controller.isCheckCPButtonWarn,
-            ),
-          ],
-        ),
-        const SizedBox(height: 12),
-      ]);
-    }
-
-    return Padding(
-        padding: const EdgeInsets.only(left: 12, right: 12),
-        child: Column(
-          children: children,
-        ));
-  }
-
-  void _onBrightness() async {
-    await controller.setIsBrightnessMax(!controller.isBrightnessMax);
-    setState(() {});
-  }
-
-  Future<void> _toSettings() async {
-    await controller.toSettings();
-    if(mounted){
-      setState(() {});
-    }
-  }
-
-  void _showInfo() {
-    Get.to(() => InfoView());
-  }
-
-  void onClickCompassLevel() {
-    var l = controller.compassLevel.value;
-    l++;
-    if (l > Compass2.levelMax) {
-      l = Compass2.levelMin;
-    }
-    controller.compassLevel.value = l;
-  }
-}
-
-class _Button extends StatelessWidget {
-  const _Button({
-    required this.icon,
-    this.onPressed,
-    this.isSelected = false,
-    this.disableSrc,
-  });
-
-  final bool isSelected;
-  final Widget icon;
-  final VoidCallback? onPressed;
-  final String? disableSrc;
-
-  @override
-  Widget build(BuildContext context) {
-    const s = 46.0;
-
-    final children = <Widget>[
-      SizedBox(
-          width: s,
-          height: s,
-          child: onPressed != null ? icon : Image.asset(disableSrc!))
-    ];
-
-    if (isSelected && onPressed != null) {
-      children.add(Image.asset(
-        'assets/images/btn_boader.png',
-        width: s,
-        height: s,
-      ));
-    }
-
-    return GestureDetector(
-      onTap: onPressed,
-      child: Stack(
-        children: children,
-      ),
-    );
-  }
-}
-
-void main() async {
-  runPreview(const LayerButtonBar(
-    isShowCheckCPButton: true,
-    isCheckCPButtonEnable: true,
-  ));
-
-}

+ 0 - 31
lib/view/ingame/game_std/layer_location.dart

@@ -1,31 +0,0 @@
-import 'package:trackoffical_app/model.dart';
-import 'package:trackoffical_app/screen.dart';
-
-import '../../../widget/my_position_point.dart';
-import 'game_std_controller.dart';
-
-class LayerLocation extends LayerView<GameStdController>{
-  const LayerLocation({super.key});
-
-  @override
-  Widget build(BuildContext context) {
-    return Layer(children: [
-      Obx((){
-        var p = viewModel.instance.model.myPositionOnMap;
-        if (p == null) {
-          return const SizedBox();
-        }
-        p = viewModel.mapOffsetToScreen(p);
-
-        var direction = 0.0;
-
-        if(viewModel.mapRotationMode.value==MapMode.original){
-          direction = viewModel.matrixRotation -viewModel.instance.compassRadiansFused.value;
-        }
-
-
-        return MyPositionPoint(offset: p, color: Colors.red, radius: 4.4.wp, direction: direction);
-      })
-    ]);
-  }
-}

+ 0 - 34
lib/view/ingame/game_std/layer_map_ruler.dart

@@ -1,34 +0,0 @@
-import '../widget_ruler.dart';
-import 'game_std_controller.dart';
-
-class LayerMapRuler extends LayerView<GameStdController> {
-  const LayerMapRuler({super.key});
-
-  @override
-  Widget build(BuildContext context) {
-    return Obx(() {
-      if (viewModel.isShowRuler.value) {
-        final mapScale = viewModel.mapScale;
-        if (mapScale == 0) {
-          return const SizedBox();
-        }
-
-        var height = context.height / 2;
-        var hideHeight = 0.0;
-
-        if (viewModel.isMapRotateAtCompassCenter.value) {
-          height = viewModel.compassCenter.dy;
-          hideHeight = viewModel.compassDiameter / 2 + 1;
-        }
-
-        return Container(
-            alignment: Alignment.topCenter,
-            padding: EdgeInsets.only(top: context.mediaQueryPadding.top),
-            height: height,
-            child: Ruler(hideHeight: hideHeight, mapScale: mapScale));
-      } else {
-        return const SizedBox();
-      }
-    });
-  }
-}

+ 0 - 96
lib/view/ingame/game_std/layer_warn.dart

@@ -1,96 +0,0 @@
-import 'package:trackoffical_app/screen.dart';
-import 'package:trackoffical_app/service/app.dart';
-import 'game_std_controller.dart';
-import 'package:trackoffical_app/appcore/ffi.dart' as ffi;
-
-class LayerWarn extends LayerView<GameStdController> {
-  const LayerWarn({super.key});
-
-  @override
-  Widget build(BuildContext context) {
-
-    return Obx(() {
-      String? warnTitle;
-      String? warnContent;
-      Color background = Colors.transparent;
-      final mask = Colors.white.withAlpha((255 * 0.7).toInt());
-
-      if (viewModel.isShowPhoneHorizontalWarn && !viewModel.instance.isPersonMoving) {
-        warnContent = '请水平放置手机\n以获取准确方向';
-
-      }
-
-      if(App.to.userProfile.gameSettingsHotZonePrompt.value){
-        final zone = viewModel.instance.model.zone.value;
-        if (zone != null) {
-          background = mask;
-        }
-        switch (zone) {
-          case ffi.ZoneType.Road:
-            warnTitle = '道路';
-            warnContent = '您在穿越车行道路,请抬头注意安全!';
-            break;
-          case ffi.ZoneType.River:
-            warnTitle = '靠近河流';
-            warnContent = '您正在靠近河流,请抬头注意安全!';
-            break;
-          case ffi.ZoneType.Lake:
-            warnTitle = '靠近湖泊';
-            warnContent = '您正在靠近湖泊,请抬头注意安全!';
-            break;
-          case ffi.ZoneType.ParkingLot:
-            warnTitle = '停车场';
-            warnContent = '您在停车场区域,请抬头注意安全!';
-            break;
-          case ffi.ZoneType.ForbiddenZone:
-            warnTitle = '禁区';
-            warnContent = '您正在穿行禁区,请尽快离开!';
-            break;
-          case ffi.ZoneType.Lawn:
-            warnTitle = '草坪';
-            warnContent = '请勿踩踏草坪,请尽快离开!';
-            break;
-          default:
-            break;
-        }
-      }
-
-      if (viewModel.isShowOutBoundaryWarn) {
-        warnTitle = '您已离开场地';
-        warnContent = '请返回';
-        background = const Color(0x80ff870d);
-      }
-      final style = TextStyle(color: Colors.red, fontSize: 5.11.wp);
-
-      return warnContent != null
-          ? Container(
-              width: double.infinity,
-              height: double.infinity,
-              color: background,
-              alignment: Alignment.topCenter,
-              child:
-                Container(
-                    width: 44.0.wp ,
-                    margin: EdgeInsets.only(top: 30.0.wp),
-                    padding: const EdgeInsets.all(6),
-                    decoration: BoxDecoration(
-                        border: Border.all(color: const Color(0xffff870d)),
-                        color: Colors.orangeAccent.withAlpha(80),
-                        borderRadius: BorderRadius.circular(7)),
-                    child: Column(
-                      mainAxisSize: MainAxisSize.min,
-                      children: [
-                        warnTitle != null
-                            ? Text(warnTitle, style: style)
-                            : const SizedBox(),
-                        Text(
-                          warnContent,
-                          style: style.copyWith(fontSize: 4.58.wp),
-                        ),
-                      ],
-                    ))
-            )
-          : const Positioned(child: SizedBox());
-    });
-  }
-}

+ 0 - 281
lib/view/ingame/game_std/route_planning.dart

@@ -1,281 +0,0 @@
-import 'dart:async';
-
-import 'package:fixnum/fixnum.dart';
-import 'package:get/get.dart';
-import 'package:flutter/material.dart';
-import 'package:trackoffical_app/generated/assets.dart';
-import 'package:trackoffical_app/logger.dart';
-import 'package:trackoffical_app/model/m_control_point.dart';
-import 'package:trackoffical_app/screen.dart';
-import 'package:trackoffical_app/service/game/game_model.dart';
-import 'package:trackoffical_app/view/ingame/utils.dart';
-
-
-class RoutePlanning extends StatefulWidget {
-  const RoutePlanning({super.key,
-    required this.want,
-    required this.nextPlanPoint,
-    required this.nextWantPoint,
-    required this.onClick});
-
-  final List<MControlPoint> want;
-  final MControlPoint? nextPlanPoint;
-  final MControlPoint? nextWantPoint;
-  final void Function (MControlPoint point) onClick;
-
-
-  @override
-  State<StatefulWidget> createState() {
-    return RoutePlanningState();
-  }
-}
-const _iconSize = 6.0;
-const _rowSpace = 5.23;
-const _columSpace = 20.0;
-const _pointWidth = 18.0;
-
-
-class RoutePlanningState extends State<RoutePlanning> {
-  var contentHeight=0.0;
-
-  @override
-  Widget build(BuildContext context) {
-    return DefaultTextStyle(style: context.textTheme.bodyLarge??const TextStyle(), child: Container(
-        margin: EdgeInsets.fromLTRB(5.6.wp, 11.45.wp, 5.6.wp, 11.45.wp),
-        padding:  EdgeInsets.all(5.3.wp),
-        decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(2.29.wp)),
-        child: Column(
-          crossAxisAlignment: CrossAxisAlignment.center,
-          children: [
-            Text('路径规划', style: context.textTheme.titleLarge?.copyWith(fontSize: 5.6.wp)),
-            SizedBox(height: 4.0.wp,),
-            Expanded(child: LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) {
-              final height = constraints.maxHeight;
-              final iconSize = _iconSize.wp;
-              final rowSpace = _rowSpace.wp;
-              final columSpace = _columSpace.wp;
-              final pointWidth = _pointWidth.wp;
-
-              final rowCount = (height - rowSpace) ~/ (rowSpace + iconSize);
-              final contentHeight = rowCount * (rowSpace + iconSize);
-
-              final columCount = (widget.want.length.toDouble() / rowCount).ceil();
-              final width = (columSpace+pointWidth) * (columCount);
-
-              final colum = <Widget>[];
-              var index = 0;
-              for(var i=0; i< columCount; i++){
-                var row = <Widget>[];
-                final isOdd = i % 2 == 1;
-
-                for(var j=0; j< rowCount; j++){
-                  if(index == widget.want.length){
-                    break;
-                  }
-                  final point = widget.want[index];
-
-
-                  Widget? next;
-
-                  if(widget.nextWantPoint?.intId==point.intId){
-                    next = Image.asset(Assets.imagesWarnRun, height: 7.0.wp, color: Colors.grey);
-                  }
-                  if(widget.nextPlanPoint?.intId==point.intId){
-                    next = Image.asset(Assets.imagesWarnRun, height: 7.0.wp, color: Colors.black);
-                  }
-
-
-                  row.addAll([
-                    Row(
-                      children: [
-                        Container(width: columSpace, alignment: Alignment.centerRight, child: next),
-                        GestureDetector(
-                            onTap: ()=>widget.onClick(point),
-                            child: SizedBox(
-                                width: pointWidth,
-                                child: Column(
-                                  crossAxisAlignment: CrossAxisAlignment.start,
-                                  children: [
-                                    (point.isFinish && isOdd) || point.isStart? SizedBox(height: rowSpace/2):
-                                    Container(
-                                      margin: EdgeInsets.only(left: iconSize/2-0.5.wp/2),
-                                      height: rowSpace/2,
-                                      width: 0.5.wp,
-                                      color: const Color(0xff707070),
-                                    ),
-                                    Row(
-                                      children: [
-                                        _icon(point, iconSize),
-                                        Text(' ${point.snString}', style: TextStyle(fontSize: 3.56.wp),)
-                                      ],
-                                    ),
-                                    point.isFinish && !isOdd? const SizedBox():
-                                    Container(
-                                      margin: EdgeInsets.only(left: iconSize/2-0.5.wp/2),
-                                      height: rowSpace/2,
-                                      width: 0.5.wp,
-                                      color: const Color(0xff707070),
-                                    )
-                                  ],
-                                )
-                            )
-                        ),
-                      ],
-                    ),
-
-
-                  ] );
-                  index++;
-                }
-
-
-
-                if(isOdd){
-                  row=row.reversed.toList();
-                }
-
-                colum.add(SizedBox(height: contentHeight, child: Column(
-                    mainAxisAlignment: !isOdd? MainAxisAlignment.start: MainAxisAlignment.end,
-                    mainAxisSize: MainAxisSize.max,
-                    children: row)))   ;
-              }
-
-              return ListView(
-                scrollDirection: Axis.horizontal,
-                children: [
-                  SizedBox(
-                    height: height,
-                    width: width,
-                    child: Column(
-                      children: [
-                        CustomPaint(painter: _BottomPainter(columCount, false), size: Size(width, rowSpace/2)),
-                        Row(
-                          mainAxisSize: MainAxisSize.min,
-                          children: colum,
-                        ),
-                        CustomPaint(painter: _BottomPainter(columCount, true), size: Size(width, rowSpace/2))
-                      ],
-                    ),
-                  )
-                ],
-              );
-            })),
-            FilledButton(onPressed: ()=>Get.back(), child: const Text('返回'))
-          ],
-        )
-    ) );
-  }
-}
-Widget _icon(MControlPoint point, double iconSize){
-  var w = point.icon(height: iconSize);
-  if(!point.isSuccess){
-    if(point.isFinish){
-      w = Image.asset(Assets.imagesIcCpFinishUncheck, height: iconSize,);
-    }else{
-      w = Image.asset(Assets.imagesIcCpUncheck, height: iconSize);
-    }
-  }
-
-  return w;
-}
-
-
-class _BottomPainter extends CustomPainter{
-  _BottomPainter(this.columCount, this.isBottom);
-
-  final int columCount;
-  final bool isBottom;
-  final iconSize = _iconSize.wp;
-  final rowSpace = _rowSpace.wp;
-  final columSpace = _columSpace.wp;
-  final pointWidth = _pointWidth.wp;
-
-  @override
-  void paint(Canvas canvas, Size size) {
-
-    final paint = Paint()
-      ..color=const Color(0xff707070)
-      ..strokeWidth=0.5.wp
-      ..style=PaintingStyle.stroke;
-    
-    for(var i=0; i< columCount; i++){
-      final isOdd = i%2==1;
-      if(isBottom){
-        if(!isOdd){
-          continue;
-        }
-      }else{
-        if(i==0){
-          continue;
-        }
-        if(isOdd){
-          continue;
-        }
-      }
-
-      final path = Path();
-      var x = 0.0;
-      var y = 0.0;
-
-
-      x = iconSize/2 + columSpace + (columSpace + pointWidth) * i;
-      if(!isBottom){
-        y=size.height;
-      }
-
-      path.moveTo(x, y);
-
-      if(isBottom){
-        y+= size.height;
-      }else{
-        y-= size.height-1;
-      }
-
-      path.lineTo(x, y);
-      x -= columSpace+pointWidth;
-      path.lineTo(x, y);
-
-      if(isBottom){
-        y-= size.height;
-
-      }else{
-        y+=size.height;
-      }
-      path.lineTo(x, y);
-      canvas.drawPath(path, paint);
-    }
-    
-  }
-
-  @override
-  bool shouldRepaint(covariant CustomPainter oldDelegate) {
-    return false;
-  }
-
-}
-
-
-
-
-void main(){
-  final want = <MControlPoint>[];
-  for(var i=0; i< 15; i++){
-    want.add(MControlPoint()
-      ..sn='$i'
-      ..intId=Int64(i)
-      ..isSuccess=i<8);
-  }
-
-  want[0].isStart=true;
-  want.last.isFinish=true;
-
-  runPreview(Scaffold(
-    body: RoutePlanning(
-      want: want,
-      nextPlanPoint: want[2],
-      nextWantPoint: want[3], onClick: (MControlPoint point) {
-        debug('点击 ${point.snString}');
-    },
-    ),
-  ));
-}

+ 0 - 36
lib/view/ingame/game_std/settlement_view.dart

@@ -1,36 +0,0 @@
-import 'package:trackoffical_app/screen.dart';
-import 'package:trackoffical_app/service/game/game_instance_std/game_instance_std.dart';
-import 'game_std_controller.dart';
-
-
-class SettlementView extends GetView<LayerController>{
-  const SettlementView({super.key});
-  GameStdController get c => controller as GameStdController;
-
-  @override
-  Widget build(BuildContext context) {
-    return Scaffold(
-      body: Center(
-        child: Column(
-          crossAxisAlignment: CrossAxisAlignment.center,
-          mainAxisSize: MainAxisSize.min,
-          children: [
-            Obx(() => Text(c.settlementTip.value, style: context.textTheme.titleLarge)),
-            Image.asset(
-              'assets/images/loading.gif',
-              height: 60,
-              width: 60,
-            )
-          ],
-        )
-      ),
-    );
-  }
-
-}
-
-
-void main() async {
-  Get.put(GameStdController(GameInstanceStd(gameState:GameState())));
-  runPreview(const SettlementView());
-}

+ 0 - 249
lib/view/ingame/game_std/utils.dart

@@ -1,249 +0,0 @@
-import 'package:trackoffical_app/model/game_person_data.dart';
-import 'package:trackoffical_app/model/m_control_point.dart';
-import 'package:trackoffical_app/utils.dart';
-import 'package:screen_brightness/screen_brightness.dart';
-import '../../../widget/app_dialog.dart';
-import '../checked_cp_record.dart';
-import 'game_std_controller.dart';
-
-
-
-
-extension MCPExt on MControlPoint{
-  Widget display({TextStyle? textStyle, double? height}){
-    final next = this;
-    if (next.sn == MControlPoint.snStart || next.sn == MControlPoint.snFinish) {
-      var src = 'ic_bottom_bar_next_start.png';
-      if (next.sn == MControlPoint.snFinish) {
-        src = 'ic_bottom_bar_next_finish.png';
-      }
-      return Image.asset(
-        'assets/images/$src',
-        height: height??22,
-        fit: BoxFit.fitHeight,
-        color: Colors.white,
-      );
-    }
-    return Text(next.sn, style: textStyle);
-  }
-
-  Widget icon({double? height}){
-    final next = this;
-    var src = 'ic_cp.png';
-    if(next.isStart){
-      src = 'ic_cp_start.png';
-    }
-    if(next.isFinish){
-      src = 'ic_cp_finish.png';
-    }
-
-    return Image.asset(
-      'assets/images/$src',
-      height: height??22,
-      fit: BoxFit.fitHeight,
-    );
-  }
-
-}
-extension MCPNullableExt on MControlPoint?{
-  Widget display({TextStyle? textStyle, double? height}){
-    Widget text;
-    final nextCp = this;
-    if (nextCp != null) {
-      text = nextCp.display(textStyle: textStyle);
-      if (nextCp.areaId.isNotEmpty && nextCp.type == MControlPointType.nfc) {
-        text = Row(
-          mainAxisSize: MainAxisSize.min,
-          children: [
-            text,
-            Text(
-              ' (${nextCp.areaId})',
-              style: textStyle,
-            )
-          ],
-        );
-      }
-    } else {
-      text = Text('--', style: textStyle, maxLines: 1);
-    }
-
-    return text;
-  }
-}
-
-
-class _TwoValueElem extends  StatelessWidget{
-  const _TwoValueElem({
-    required this.value1,
-    required this.value2,
-    required this.unit,
-    required this.fontSize
-  });
-
-  final String value1;
-  final String value2;
-  final String unit;
-  final double fontSize;
-
-  @override
-  Widget build(BuildContext context) {
-    final small = fontSize * 0.875;
-    final unitSize = small -2;
-
-    return Row(
-      children: [
-        Expanded(child: Column(
-          mainAxisSize: MainAxisSize.min,
-          children: [
-            SizedBox(
-                width: context.width,
-                child: Text(value1,
-                    maxLines: 1,
-                    style: TextStyle(fontSize: small))),
-            Container(height: 1, width: context.width, color: Colors.white,),
-            SizedBox(
-                width: context.width,
-                child: Text(value2,
-                    maxLines: 1,
-                    textAlign: TextAlign.end,
-                    style: TextStyle(fontSize: fontSize))),
-          ],
-        )),
-        const SizedBox(width: 5),
-        Text(unit, style: TextStyle(fontSize: unitSize))
-      ],
-    );
-  }
-
-}
-
-
-
-extension GameModelExt on GamePersonData{
-  Widget widgetDistance({double fontSize = 17.4, bool withTrip = true}) {
-    final small = fontSize * 0.875;
-    final unitSize = small -2;
-    if (withTrip){
-      return _TwoValueElem(
-          value1: (myPositionHistoryLenFromLastCP.m).round().toString(),
-          value2: (myPositionHistoryLen.value.m).round().toString(),
-          unit: 'm',
-          fontSize: fontSize);
-    }else{
-      var unit = ' km';
-      var value = '--';
-
-      (value, unit) = myPositionHistoryLen.value.toStringValueAndUnit();
-
-      return RichText(text: TextSpan(
-        text: value,
-        style: TextStyle(fontSize: fontSize),
-        children: [
-          TextSpan(text: unit, style:  TextStyle(fontSize: unitSize))
-        ]
-      ));
-    }
-  }
-
-
-  String paceString(Duration pace){
-    if(pace.inMinutes> 99){
-      return '99+\'';
-    }
-    return pace.toMinSecondString();
-  }
-
-  Widget widgetPace({double fontSize = 17.4, bool withTrip = true}) {
-    final small = fontSize * 0.875;
-    final unitSize = small -2;
-    if (withTrip){
-      return _TwoValueElem(
-          value1: paceString(paceSecondKmFromLastCP.value),
-          value2: paceString(paceSecondKm.value),
-          unit: '/km',
-          fontSize: fontSize);
-    }else{
-
-      return RichText(text: TextSpan(
-          text: paceString(paceSecondKm.value),
-          style: TextStyle(fontSize: fontSize),
-          children: [
-            TextSpan(text: '/km', style:  TextStyle(fontSize: unitSize))
-          ]
-      ));
-    }
-  }
-}
-
-Widget wSport(String value, String iconSrc, {TextStyle? textStyle}) {
-  return Column(
-    mainAxisSize: MainAxisSize.min,
-    crossAxisAlignment: CrossAxisAlignment.center,
-    children: [
-      Text(value, maxLines: 1, overflow: TextOverflow.clip, style: textStyle),
-      Image.asset(iconSrc, height: 14.16)],
-  );
-}
-void showCheckedPoints(List<MControlPoint> data) {
-  final textStyle = Get.theme.textTheme.titleLarge;
-  Get.dialog(
-    Card(
-        color: Colors.white,
-        surfaceTintColor: Colors.white,
-        margin: const EdgeInsets.fromLTRB(40, 50, 40, 100),
-        child: Padding(
-          padding: const EdgeInsets.all(20),
-          child: Column(
-            children: [
-              Text('打点记录', style: textStyle),
-              const SizedBox(height: 12),
-              Expanded(
-                child: CheckedCPRecord(
-                  data: data,
-                ),
-              ),
-              // SizedBox(
-              //   child: CheckPointRecord(data: controller.checkedPointHistory),
-              // ),
-              FilledButton(
-                  onPressed: () => Get.back(), child: const Text('确定'))
-            ],
-          ),
-        )),
-  );
-}
-
-
-Widget getSmallTitle(String title){
-  return Container(
-      alignment: Alignment.center,
-      padding: const EdgeInsets.only(left: 3, right: 3),
-      decoration: const BoxDecoration(color: Colors.black),
-      child: Text(title,
-          style: const TextStyle(
-              fontSize:11,
-              color: Colors.white,
-              fontWeight: FontWeight.w700))
-  );
-}
-
-Future<bool> get isBrightnessMax async{
-  final b = await ScreenBrightness().current;
-  return b>=1;
-}
-
-
-
-void onButtonExit(GameStdController controller) {
-  Get.dialog(AppDialog(
-    title: const Text('退出比赛'),
-    content: const Text('是否强制结束?'),
-    onConfirm: (){
-      Get.back();
-      controller.forceExit();
-    } ,
-    onCancel: () => Get.back(),
-    onConfirmText: '是',
-    onCancelText: '否',
-  ));
-}

+ 0 - 517
lib/view/ingame/in_game_controller.dart

@@ -1,517 +0,0 @@
-import 'dart:async';
-import 'dart:io';
-import 'package:assets_audio_player/assets_audio_player.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/services.dart';
-import 'package:get/get.dart';
-import 'package:get_storage/get_storage.dart';
-import 'package:trackoffical_app/generated/assets.dart';
-import 'package:trackoffical_app/model.dart';
-import 'package:trackoffical_app/pb.dart' as pb;
-import 'package:trackoffical_app/service/app.dart';
-import 'package:trackoffical_app/service/game/game_model.dart';
-import 'package:trackoffical_app/service/sport_wear.dart';
-import 'package:screen_brightness/screen_brightness.dart';
-import '../game_settings.dart';
-import 'dialog/dialog_base.dart';
-import 'dialog/dialog_confirm_finish.dart';
-import 'dialog/dialog_cp_order_err.dart';
-import 'dialog/dialog_check_rich2.dart';
-import 'dialog/dialog_check_text.dart';
-import 'package:trackoffical_app/widget/compass2.dart';
-import '../../model/m_control_point.dart';
-import 'settlement_view.dart';
-import '../../logger.dart';
-import 'package:nfc_manager/nfc_manager.dart';
-import '../../service/game/game.dart';
-import '../../utils.dart';
-import 'package:nfc_manager/platform_tags.dart';
-import 'package:vector_math/vector_math_64.dart' as vec;
-import 'package:sensor/sensor.dart' as sensor;
-
-
-class InGameController extends GetxController {
-  static double bottomBarHeight = 120.0;
-  final service = GameService.to;
-  bool get isShowCompass => service.isShowCompass.value;
-  DateTime? get startAt => GameService.to.startAt;
-  Duration get maxDuration => GameService.to.maxPassDuration;
-  double compassAngleDegree = 0.0;
-  DateTime? lastGyroscopeTime;
-  bool get isNfcScanUseDialog => GameService.to.isNfcScanUseDialog;
-  List<MControlPoint> get checkedPointHistory => GameService.to.checkedPointsHistory;
-  final isShowTimeBar = true.obs;
-  final phoneX = 0.obs;
-  final phoneY = 0.obs;
-  final legend = GameService.to.gameState.pbGameData.legendImage.toModel();
-  Function? disposeListen;
-  final GameModel _model = Get.find();
-  StreamSubscription<double>? _compassSubscription;
-  StreamSubscription<MPosition?>? _myPositionSubscription;
-  final compassLevel = Compass2.levelMin.obs;
-  final isMapRotateAtCompassCenter = false.obs;
-  /// 是否显示下一个点的方向
-  final isShowNextCPRadians = true.obs;
-  final isShowRuler = false.obs;
-  var _compassSizeIndex = 0;
-  final _compassSizeList = <double>[160.0, 200, 240, 280];
-  final uiMode = App.to.userProfile.gameSettingsUIMode.value.obs;
-  final _isUseRealNorth = Get.find<GameModel>().isUseRealNorth.obs;
-  bool get isUseRealNorth => _isUseRealNorth.value;
-  set isUseRealNorth(v){
-    _isUseRealNorth.value=v;
-    _model.isUseRealNorth=v;
-  }
-  final _isInGameUISimplifyMode = App.to.userProfile.isInGameUISimplifyMode.val.obs;
-  bool get isInGameUISimplifyMode => _isInGameUISimplifyMode.value;
-  set isInGameUISimplifyMode(v){
-    _isInGameUISimplifyMode.value=v;
-    App.to.userProfile.isInGameUISimplifyMode.val=v;
-  }
-  final _isEnableOutBoundaryWarn = App.to.userProfile.isEnableOutBoundaryWarn.val.obs;
-  bool get isEnableOutBoundaryWarn => _isEnableOutBoundaryWarn.value;
-  set isEnableOutBoundaryWarn(v){
-    _isEnableOutBoundaryWarn.value=v;
-    App.to.userProfile.isEnableOutBoundaryWarn.val=v;
-  }
-  final _audioPlayer =  AssetsAudioPlayer.newPlayer();
-  bool get isEnableUserLocation=>_model.isEnableUserLocation;
-  set isEnableUserLocation(v){
-    _model.isEnableUserLocation=v;
-  }
-
-  final isStartShowWarn = _StorageValue(App.to.userProfile.isStartShowWarn);
-  final isEnableGameSound = _StorageValue(App.to.userProfile.isEnableGameSound);
-  final isEnableGameVibrate = _StorageValue(App.to.userProfile.isEnableGameVibrate);
-  final isEnableGameCulture = _StorageValue(App.to.userProfile.isEnableGameCulture);
-  final isEnableInGameStartCPBubble = _StorageValue(App.to.userProfile.isEnableInGameStartCPBubble);
-  bool get isShowOutBoundaryWarn =>  isEnableOutBoundaryWarn && service.isOutBoundary;
-
-  bool get isBrightnessMax => App.to.userProfile.isEnableInGameBrightnessMax.val;
-  Future<void> setIsBrightnessMax(bool v)async{
-    App.to.userProfile.isEnableInGameBrightnessMax.val=v;
-    if (v) {
-      await ScreenBrightness().setScreenBrightness(1);
-    } else {
-      await ScreenBrightness().resetScreenBrightness();
-    }
-  }
-  Future<void> toSettings()async{
-    await Get.to(() => const GameSettingsView(isInGame: true));
-  }
-
-  double? get nextControlPointDistanceKm{
-    final real = _model.nextPlanCPDistanceKm;
-    if(real == null){
-      return null;
-    }
-
-    var show = real.km - _model.controlPointEffectiveAreaRadiusKm
-        + GameModel.controlPointEffectiveAreaRadiusKmOffset;
-    if(show < 0 ){
-      show = 0;
-    }
-    return show;
-  }
-  final _trajectorySeconds = App.to.userProfile.inGameTrajectorySeconds.val.obs;
-  int get trajectorySeconds => _trajectorySeconds.value;
-  set trajectorySeconds(v){
-    _trajectorySeconds.value=v;
-    App.to.userProfile.inGameTrajectorySeconds.val=v;
-  }
-
-  Offset get compassCenter => Offset(
-      App.to.screenSize.width/2,
-      App.to.screenSize.height - bottomBarHeight - compassDiameter/2);
-
-  double get compassDiameter => _model.compassDiameter.value;
-  sensor.Orientation get orientation => _model.orientation.value;
-  bool get isPhoneHorizontal{
-    final x = vec.degrees(orientation.x);
-    final y = vec.degrees(orientation.y);
-    if (x.abs() > 30 || y.abs()>30){
-      return false;
-    }else{
-      return true;
-    }
-  }
-  bool get isShowPhoneHorizontalWarn => (!isPhoneHorizontal)&&(!_model.isMoving);
-
-  final isNoMapRulerScaleMode = false.obs;
-  bool get isShowCheckCPButton{
-    final next = service.getNextWantPoint(0);
-    final nextPlan = _model.nextPlanPoint;
-    return  isNfcScanUseDialog || next?.type==MControlPointType.gps || nextPlan?.type==MControlPointType.gps;
-  }
-  bool get isCheckCPButtonEnable {
-    final next = service.getNextWantPoint(0);
-    final nextPlan = _model.nextPlanPoint;
-    final iosEnable = isNfcScanUseDialog
-        && (next?.type==MControlPointType.nfc || nextPlan?.type==MControlPointType.nfc);
-
-    return (_model.isInPlanControlPointArea ||_model.isInWantControlPointArea || iosEnable) && isShowCheckCPButton;
-  }
-
-  bool get isCheckCPButtonWarn => _model.isInWantControlPointArea && isCheckCPButtonEnable;
-
-  bool get isSportWearConnected => Get.find<SportWearService>().connectedSportWear.value != null;
-
-  /// 地图比例尺 1:[mapScale]
-  final Rx<double?> mapScale = Rx(null);
-  String get beginDurationStr {
-    final startAt = this.startAt;
-
-    if (startAt == null) {
-      return '00:00:00';
-    } else {
-      final countDown = GameService.to.beginDuration.value;
-      var s = countDown.inSeconds;
-      final h = (s / 3600).floor();
-      final hStr = h.twoDigits();
-      final m = ((s - h * 3600) / 60).floor();
-      final mStr = m.twoDigits();
-      final sStr = (s - h * 3600 - m * 60).twoDigits();
-      return '$hStr:$mStr:$sStr';
-    }
-  }
-
-  /// 下个点方向弧度
-  double? get nextCPRadians {
-    final p0 = _model.myPosition.value;
-    final p1 = _model.nextPlanPoint?.position;
-
-    if(p0 == null || p1 == null){
-      return null;
-    }
-    return _model.compassRadiansFused.value + p0.directionTo(p1);
-  }
-
-  void setRotateCenterToScreenCenter(){
-    _model.setRotateCenterToScreenCenter();
-  }
-  void setRotateCenterToCompassCenter(){
-    _model.mapRotateCenter = compassCenter;
-  }
-  void flushRotateCenter(){
-    if (isMapRotateAtCompassCenter.value) {
-      setRotateCenterToCompassCenter();
-    } else {
-      setRotateCenterToScreenCenter();
-    }
-    if(_model.isLockScreenCenterToMyPositionSystem){
-      service.showLocation();
-    }
-
-  }
-
-  void showCompassSwitch() {
-    service.isShowCompass.value = !service.isShowCompass.value;
-  }
-  void showTimeSwitch(){
-    isShowTimeBar.value = !isShowTimeBar.value;
-  }
-  var _lastRelocateTime = DateTime.now();
-  @override
-  void onReady() {
-    final box = GetStorage();
-    disposeListen = box.listen((){
-      uiMode.value = App.to.userProfile.gameSettingsUIMode.value;
-    });
-
-    setIsBrightnessMax(isBrightnessMax);
-
-    onRequestData().then((value) => info('数据加载成功'));
-    final gameService = GameService.to;
-    final mapStatus = gameService.mapStatus;
-
-
-    _compassSubscription = _model.compassRadiansFused.listen((v) {
-      if (mapStatus.mapMode.value == MapMode.compass) {
-        gameService.setBeginMatrix();
-        mapStatus.setRotate(v);
-      }
-    });
-
-    _myPositionSubscription = _model.myPosition.listen((p0) {
-      if(p0 != null && _model.isLockScreenCenterToMyPositionSystem){
-        final now = DateTime.now();
-        if(now.difference(_lastRelocateTime) > 100.milliseconds){
-          gameService.showLocation();
-          _lastRelocateTime = now;
-        }
-      }
-
-    });
-
-    if (!isNfcScanUseDialog){
-      NfcManager.instance.startSession(
-          onDiscovered: _onNfcDiscovered, alertMessage: '保持NFC靠近');
-      info('Nfc开始扫描');
-    }
-
-
-    workPlayDistanceSound();
-  }
-
-  Future<void> _onNfcDiscovered(NfcTag tag) async {
-    info("NFC: \n ${tag.data}");
-    String identifier = "";
-
-
-    if (Platform.isAndroid) {
-      identifier = (NfcA.from(tag)?.identifier ??
-              NfcB.from(tag)?.identifier ??
-              NfcF.from(tag)?.identifier ??
-              NfcV.from(tag)?.identifier ??
-              Uint8List(0))
-          .toHexString();
-    }
-    if (Platform.isIOS) {
-      identifier = (Iso15693.from(tag)?.identifier ??
-          Iso7816.from(tag)?.identifier ??
-          MiFare.from(tag)?.identifier ??
-          Uint8List(0))
-          .toHexString();
-    }
-
-    info('Id: $identifier');
-
-    GameService.to.checkPointNFC(
-      identifier,
-      _onChecked,
-      _onConfirmFinish,
-      _onProjectPoint,
-      _onNoPoint
-    );
-  }
-
-  Future<void> onCheckControlPoint() async {
-    final next = _model.getNextWantPoint(0);
-    if(next != null){
-      switch (next.type){
-        case MControlPointType.nfc:
-          await onIosNfcStart();
-          break;
-        case MControlPointType.gps:
-          await GameService.to.checkPointGps(
-            _onChecked, _onConfirmFinish
-          );
-          break;
-      }
-    }
-  }
-
-  Future<void> onCheckGpsControlPoint() async {
-    GameService.to.checkPointGps(
-        _onChecked, _onConfirmFinish
-    );
-  }
-  Future<void> onSwitchCompassSize() async {
-    _compassSizeIndex++;
-    if(_compassSizeIndex>=_compassSizeList.length){
-      _compassSizeIndex=0;
-    }
-
-    _model.compassDiameter.value = _compassSizeList[_compassSizeIndex];
-    flushRotateCenter();
-  }
-
-
-  _closeExistDialog(){
-    if(Get.isOverlaysOpen){
-      Get.back();
-    }
-  }
-
-  _playCheckSound(MControlPoint cp) async{
-    if(cp.isFinish){
-      return;
-    }
-    await Future.delayed(200.milliseconds);
-    var src = cp.isSuccess? 'assets/sound/ok.wav': 'assets/sound/fail.wav';
-    if(!cp.isSuccess && cp.isPlan){
-      src = Assets.soundPlanOk;
-    }
-
-
-    if(isEnableGameSound.value) {
-      AssetsAudioPlayer.newPlayer().open(
-        Audio(src),
-        autoStart: true,
-        showNotification: false,
-      );
-    }
-  }
-
-  Future<bool> _onConfirmFinish()async{
-    return true;
-    return await dialogAskConfirmFinish();
-  }
-
-  _onChecked(MControlPoint cp){
-    _closeExistDialog();
-
-    final status = GameService.to.status;
-    info('状态:$status');
-
-    final isOver = [GameStatus.settlement, GameStatus.idle].contains(status);
-
-    final next = GameService.to.getNextWantPoint(0);
-    onConfirm(){
-      if(isOver){
-        SettlementView.show();
-      }
-    }
-
-    _playCheckSound(cp);
-    if(cp.isSuccess){
-      if(cp.isStart){
-        Get.dialog(DialogCheckText(text: '开始', color: Colors.white, autoPlayAfter: 200.milliseconds,));
-      }else if(cp.isFinish){
-        onConfirm();
-      }else{
-        showDialogCheckRich(cp, _model.gameQuestionShowDuration).then((value) {
-          service.save();
-          onConfirm();
-        } );
-
-      }
-    }else{
-      if(isOver){
-        onConfirm();
-      }else{
-        if(cp.isPlan){
-          Get.dialog(const DialogCheckText(
-            text: '已打点', color: Color(0xffff870d),
-          ));
-        }else if(next!= null){
-          dialogCPOrderErr(next);
-        }else{
-          Get.dialog(const DialogCheckText(text: '打点错误', color: Colors.red));
-        }
-      }
-    }
-  }
-  _onProjectPoint(pb.ControlPointSimple point){
-    _closeExistDialog();
-    _playCheckSound(MControlPoint()
-      ..isSuccess=false);
-
-    Get.dialog(dialogTitle(
-        '非线路检查点',
-        Colors.red, const Text('请检查地图线路'),
-      offAfter: 3.seconds
-    ));
-  }
-  _onNoPoint(){
-    _closeExistDialog();
-    _playCheckSound(MControlPoint()
-      ..isSuccess=false);
-
-    Get.dialog(dialogTitle(
-        '打点错误',
-        Colors.red, const Text('不是检查点'),
-        offAfter: 3.seconds
-    ));
-  }
-
-
-
-  Future<void> onIosNfcStart() async {
-    if (!(await App.to.isNfcAvailable)) {
-      Get.showSnackbar(const GetSnackBar(
-        message: 'NFC不可用',
-      ));
-      return;
-    }
-
-    NfcManager.instance.startSession(
-      alertMessage: '请靠近打卡点',
-      onDiscovered: (tag) async {
-        try {
-          await _onNfcDiscovered(tag);
-          await NfcManager.instance.stopSession(alertMessage: '打卡成功');
-        } catch (e) {
-          await NfcManager.instance.stopSession(errorMessage: '$e');
-        }
-      },
-    );
-  }
-  Future<void> onRequestData() async {}
-
-  Future<void> forceExit() async {
-    await GameService.to.gameGiveUpAndToFinishView();
-  }
-
-  Future<void> workPlayDistanceSound()async{
-    while(!isClosed){
-      final disKm = nextControlPointDistanceKm;
-      if(disKm != null  && service.endAt==null){
-        final disM = disKm * 1000;
-        var d = 5200.milliseconds;
-        String? src = 'assets/sound/beep.wav';
-        if(disM < 30){
-          d = 1200.milliseconds;
-        }
-
-        if(disM < 10){
-          d = 700.milliseconds;
-        }
-
-
-        if((_model.isInPlanControlPointArea && _model.nextPlanPoint?.type == MControlPointType.gps)
-            || (_model.isInWantControlPointArea&&  _model.getNextWantPoint(0)?.type == MControlPointType.gps)){
-
-          d = 3400.milliseconds;
-          src = 'assets/sound/punch_alarm.mp3';
-        }
-
-
-        if(isEnableGameSound.value){
-          await _audioPlayer.open(
-            Audio(src),
-            autoStart: false,
-            showNotification: false,
-          );
-          await _audioPlayer.play();
-        }
-
-        await Future.delayed(d);
-      }else{
-        await Future.delayed(500.milliseconds);
-      }
-    }
-  }
-
-
-  @override
-  void onClose() {
-    disposeListen?.call();
-    _audioPlayer.stop();
-    _myPositionSubscription?.cancel();
-    _compassSubscription?.cancel();
-    if (!isNfcScanUseDialog) {
-      NfcManager.instance.stopSession();
-    }
-    debug('停止指南');
-  }
-}
-
-class _StorageValue<T>{
-  _StorageValue(this._data): _state=_data.val.obs;
-
-  final ReadWriteValue<T> _data;
-  final Rx<T> _state;
-
-  T get value => _state.value;
-  set value(T v){
-    _state.value = v;
-    _data.val = v;
-  }
-}
-
-
-class InGameControllerMock extends InGameController {
-  @override
-  Future<void> onRequestData() async {}
-}

+ 0 - 181
lib/view/ingame/in_game_loading.dart

@@ -1,181 +0,0 @@
-import 'package:dart_jts/dart_jts.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_rust_bridge/flutter_rust_bridge.dart';
-import 'package:get/get.dart';
-import 'package:grpc/grpc.dart';
-import 'package:trackoffical_app/exception/exception.dart';
-import 'package:trackoffical_app/logger.dart';
-import 'package:trackoffical_app/route.dart';
-import 'package:trackoffical_app/service/game/game_manager_service.dart';
-import 'package:trackoffical_app/service/mock.dart';
-import 'package:trackoffical_app/styles/theme.dart';
-import 'package:trackoffical_app/view/ingame/game_guardian/guardian_watch_game_view.dart';
-import '../../service/game/game.dart';
-import 'in_game_view.dart';
-
-class InGameLoadingController extends GetxController {
-  double get loadProgress => GameService.to.loadProgress;
-  Worker? worker;
-
-  @override
-  void onReady() {
-    super.onReady();
-
-    GameService.to.gameLoad().then(
-        (value) => Get.offAll(() => const InGameView(),
-            binding: InGameView.bindings()), onError: (e) {
-      error('加载失败:', e);
-      var msg = e.toString();
-      if (e is FfiException) {
-        GameService.to.gameGiveUp();
-        msg = '地图包错误:${e.message}';
-      }
-      Get.dialog(AlertDialog(
-        icon: const Icon(Icons.error, color: Colors.red),
-        title: const Text('加载失败!'),
-        content: Text(msg),
-        actions: [
-          FilledButton(
-              onPressed: () {
-                Get.offAllNamed(RouteName.home);
-              },
-              child: const Text('确定'))
-        ],
-      ));
-    });
-  }
-
-  void onBack() {}
-}
-
-class GuardianLoadingController extends InGameLoadingController {
-  @override
-  void onReady() {
-    final underGuardianId = Get.arguments;
-    if (underGuardianId is! int) {
-      throw RuntimeException('Argument not int: ${Get.arguments}');
-    }
-
-
-
-    GameManagerService.to.guardianStart(underGuardianId).then((value) {
-      Get.off(() => const GuardianWatchGameView(),
-          binding: GuardianWatchGameView.bindings(),
-          arguments: underGuardianId);
-    }, onError: (e) {
-      if (e is FutureCancel) {
-        return;
-      }
-
-      error('加载失败:', e);
-      var msg = e.toString();
-      if (e is FfiException) {
-        msg = '地图包错误:${e.message}';
-      }
-      if (e is GrpcError) {
-        msg = '${e.message}';
-      }
-      Get.dialog(AlertDialog(
-        icon: const Icon(Icons.error, color: Colors.red),
-        title: const Text('加载失败!'),
-        content: Text(msg),
-        actions: [
-          FilledButton(
-              onPressed: () {
-                Get.offAllNamed(RouteName.home);
-              },
-              child: const Text('确定'))
-        ],
-      ));
-    });
-
-    100.milliseconds.delay().then((value){
-      final instance = GameManagerService.to.instance;
-      if(instance!=null && !isClosed){
-        _loadProgress.bindStream(instance.loadProgress.stream);
-      }
-    });
-  }
-  final _loadProgress = 0.0.obs;
-
-  @override
-  void onClose() {
-    super.onClose();
-    _loadProgress.close();
-  }
-
-
-  @override
-  double get loadProgress => _loadProgress.value;
-
-  @override
-  void onBack() {
-    GameManagerService.to.instanceStop();
-  }
-}
-
-class InGameLoadingView extends GetView<InGameLoadingController> {
-  const InGameLoadingView({super.key});
-
-  static Bindings bindingsToGame() {
-    return BindingsBuilder(() {
-      Get.lazyPut<InGameLoadingController>(() => InGameLoadingController());
-    });
-  }
-
-  static Bindings bindingsToGuardian() {
-    return BindingsBuilder(() {
-      Get.lazyPut<InGameLoadingController>(() => GuardianLoadingController());
-    });
-  }
-
-  static void toGuardian(int id) {
-    Get.to(() => const InGameLoadingView(),
-        binding: bindingsToGuardian(), arguments: id);
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    return WillPopScope(
-        onWillPop: () async {
-          controller.onBack();
-          return true;
-        },
-        child: Scaffold(
-            body: Center(
-                child: Column(mainAxisSize: MainAxisSize.min, children: [
-          Row(
-              mainAxisSize: MainAxisSize.min,
-              crossAxisAlignment: CrossAxisAlignment.center,
-              children: [
-                Text('载入中,请稍后', style: context.textTheme.titleLarge),
-                Image.asset('assets/images/loading.gif', height: 48),
-              ]),
-          const SizedBox(height: 12),
-          SizedBox(
-            height: 26,
-            width: 220,
-            child: Obx(
-                () => LinearProgressIndicator(value: controller.loadProgress)),
-          )
-        ]))));
-  }
-}
-
-class InGameLoadingControllerMock extends InGameLoadingController {
-  @override
-  void onInit() {
-    super.onInit();
-    debug('onInit');
-  }
-}
-
-void main() async {
-  Mock.initServices();
-  Get.put(GameService());
-  var c = InGameLoadingControllerMock();
-  Get.put<InGameLoadingController>(c);
-
-  runApp(
-      GetMaterialApp(theme: appThemeData(), home: const InGameLoadingView()));
-}

+ 0 - 62
lib/view/ingame/in_game_loading2.dart

@@ -1,62 +0,0 @@
-import 'package:dart_jts/dart_jts.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_rust_bridge/flutter_rust_bridge.dart';
-import 'package:get/get.dart';
-import 'package:grpc/grpc.dart';
-import 'package:trackoffical_app/exception/exception.dart';
-import 'package:trackoffical_app/logger.dart';
-import 'package:trackoffical_app/route.dart';
-import 'package:trackoffical_app/service/game/game_instance.dart';
-import 'package:trackoffical_app/service/game/game_instance_guardian.dart';
-import 'package:trackoffical_app/service/game/game_manager_service.dart';
-import 'package:trackoffical_app/service/mock.dart';
-import 'package:trackoffical_app/styles/theme.dart';
-import 'package:trackoffical_app/view/ingame/game_guardian/guardian_watch_game_view.dart';
-import '../../service/game/game.dart';
-import 'in_game_view.dart';
-
-class InGameLoadingView extends StatefulWidget {
-  const InGameLoadingView({super.key, required this.instance});
-
-  final GameInstance instance;
-
-  @override
-  State<StatefulWidget> createState() {
-    return _InGameLoadingState();
-  }
-}
-
-class _InGameLoadingState extends State<InGameLoadingView>{
-
-  @override
-  Widget build(BuildContext context) {
-    return WillPopScope(
-        onWillPop: () async {
-          return false;
-        },
-        child: Scaffold(
-            body: Center(
-                child: Column(mainAxisSize: MainAxisSize.min, children: [
-                  Row(
-                      mainAxisSize: MainAxisSize.min,
-                      crossAxisAlignment: CrossAxisAlignment.center,
-                      children: [
-                        Text('载入中,请稍后', style: context.textTheme.titleLarge),
-                        Image.asset('assets/images/loading.gif', height: 48),
-                      ]),
-                  const SizedBox(height: 12),
-                  SizedBox(
-                    height: 26,
-                    width: 220,
-                    child: Obx(
-                            () => LinearProgressIndicator(value: widget.instance.loadProgress.value)),
-                  )
-                ]))));
-  }
-}
-
-void main() async {
-  final instance = GameInstanceGuardian(underGuardianId: 1);
-  runApp(
-      GetMaterialApp(theme: appThemeData(), home: InGameLoadingView(instance:instance)));
-}

+ 0 - 404
lib/view/ingame/in_game_no_map_view.dart

@@ -1,404 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:get/get.dart';
-import 'package:trackoffical_app/utils.dart';
-import 'package:trackoffical_app/view/game_settings.dart';
-import 'package:screen_brightness/screen_brightness.dart';
-import '../sport_wear_select_view.dart';
-import 'button_punch.dart';
-import 'info_view.dart';
-import 'widget_ruler2.dart';
-import '../../widget/compass2.dart';
-import 'utils.dart';
-import 'settings_view.dart';
-import '../../service/app.dart';
-import '../../service/game/game.dart';
-import '../../service/game/game_model.dart';
-import '../../service/mock.dart';
-import '../../styles/color_schemes.g.dart';
-import 'in_game_controller.dart';
-
-class InGameNoMapView extends GetView<InGameController> {
-  InGameNoMapView({super.key});
-
-  static const _hPadding = 60.0;
-  final _model = Get.find<GameModel>();
-
-  @override
-  Widget build(BuildContext context) {
-    return Scaffold(
-        body: DefaultTextStyle(
-      style: const TextStyle(color: Colors.white),
-      child: Stack(
-        children: [
-          Obx(() => Container(
-                decoration: BoxDecoration(
-                    color: _model.heartRatePercent.value.round().toHRPColor()),
-                width: context.width,
-                height: context.height,
-              )),
-          Obx(() => !controller.isNoMapRulerScaleMode.value
-              ? const Ruler2(isScaleMode: false)
-              : const SizedBox()),
-          Container(
-              padding: EdgeInsets.only(
-                  top: context.mediaQueryPadding.top,
-                  left: _hPadding,
-                  right: _hPadding),
-              width: context.width,
-              child: Column(
-                  crossAxisAlignment: CrossAxisAlignment.center,
-                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                  children: [
-                    const SizedBox(height: 20),
-                    _topButtonBar(),
-                    _wDuration(),
-                    _process(),
-                    _topElemHub(),
-                    _compass(),
-                    _heartRate(),
-                    _sports(),
-                    _bottomBar(),
-                  ])),
-          Obx(() => controller.isNoMapRulerScaleMode.value
-              ? Ruler2(
-                  isScaleMode: true,
-                  onReturn: () =>
-                      controller.isNoMapRulerScaleMode.value = false,
-                  mapScale: controller.mapScale.value)
-              : const SizedBox(height: 0))
-        ],
-      ),
-    ));
-  }
-
-  Widget _wDuration() {
-    return Obx(() => Text(controller.beginDurationStr,
-        maxLines: 1,
-        style: const TextStyle(
-          fontSize: 29,
-          fontFamily: 'sa-digital-number',
-        )));
-  }
-
-  Widget _process() {
-    return Obx(() => Text('${_model.validCPCount}/${_model.validCPAllNum}',
-        maxLines: 1,
-        style: const TextStyle(
-          fontSize: 32,
-        )));
-  }
-
-  Widget _nextCPDistance() {
-    var unit = ' km';
-    var value = '--';
-    final km = controller.nextControlPointDistanceKm;
-    if (km != null) {
-      var i = km;
-      if (km < 1) {
-        unit = ' m';
-        i *= 1000;
-      }
-      value = i.round().toString();
-    }
-
-    return RichText(
-        text: TextSpan(
-            text: value,
-            style:
-                const TextStyle(fontSize: 28.31, fontWeight: FontWeight.w500),
-            children: [
-          TextSpan(
-              text: unit,
-              style:
-                  const TextStyle(fontSize: 13.07, fontWeight: FontWeight.w500))
-        ]));
-  }
-
-  Widget _topElemHub() {
-    const space = 6.5;
-    return Obx(() => Stack(
-          children: [
-            Column(
-              children: [
-                Row(children: [
-                  _Elem(
-                      child: _model.nextPlanPoint.display(
-                          textStyle: const TextStyle(
-                              fontSize: 21.78, fontWeight: FontWeight.w500))),
-                  const SizedBox(width: space),
-                  _Elem(
-                      child: Padding(
-                          padding: const EdgeInsets.only(left: 16, right: 16),
-                          child: _model.widgetDistance(
-                              withTrip: !controller.isInGameUISimplifyMode))),
-                ]),
-                const SizedBox(height: space),
-                Row(children: [
-                  _Elem(child: _nextCPDistance()),
-                  const SizedBox(width: space),
-                  _Elem(
-                      child: Padding(
-                          padding: const EdgeInsets.only(left: 16, right: 16),
-                          child: _model.widgetPace(
-                              withTrip: !controller.isInGameUISimplifyMode))),
-                ])
-              ],
-            ),
-            Positioned(
-                left: 0,
-                top: 0,
-                child: getSmallTitle('目标')
-            ),
-            Positioned(
-                right: 0,
-                top: 0,
-                child: getSmallTitle('里程')
-            ),
-            Positioned(
-                left: 0,
-                bottom: 0,
-                child: getSmallTitle('点距')
-            ),
-            Positioned(
-                right: 0,
-                bottom: 0,
-                child: getSmallTitle('配速')
-            ),
-          ],
-        ));
-  }
-
-  Widget _compass() {
-    return Obx(() => Compass2(
-          compassRadians: _model.compassRadiansSrc.value,
-          mapNorthRadians: _model.compassRadiansSrc.value,
-          nextPointRadians: controller.nextCPRadians,
-          level: 1,
-          showDegrees: _model.compassShowDegrees,
-          diameter: 230,
-          nextPointImage: Image.asset('assets/images/im_compass_next_arrow2.png'),
-          nextPointHeight: 100,
-          degreeColor: Colors.white,
-          plantSrc: 'assets/images/im_compass_no_map.png',
-        ));
-  }
-
-  Widget _heartRate() {
-    return Obx(() => Row(
-          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
-          children: [
-            wHrp(),
-            Container(
-                width: 1,
-                height: 53,
-                color: Colors.white.withAlpha((255 * 0.3).round())),
-            wHr(),
-          ],
-        ));
-  }
-
-  Widget wHrp() {
-    final hrp = _model.heartRatePercent.value.round();
-    return Row(
-      mainAxisSize: MainAxisSize.min,
-      crossAxisAlignment: CrossAxisAlignment.start,
-      children: [
-        Text('$hrp',
-            style: const TextStyle(fontSize: 43, fontWeight: FontWeight.w700)),
-        const Text('%',
-            style: TextStyle(fontSize: 20, fontWeight: FontWeight.w700))
-      ],
-    );
-  }
-
-  Widget wHr() {
-    return Row(
-      mainAxisSize: MainAxisSize.min,
-      crossAxisAlignment: CrossAxisAlignment.start,
-      children: [
-        Text('${_model.heartRate.value}',
-            style: const TextStyle(fontSize: 43, fontWeight: FontWeight.w700)),
-        Padding(
-            padding: const EdgeInsets.only(top: 5),
-            child: Image.asset('assets/images/ic_heart.png', height: 14.4))
-      ],
-    );
-  }
-
-  Widget _sports() {
-    const style = TextStyle(fontSize: 15.24, fontWeight: FontWeight.w500);
-
-    return Obx(() => Row(
-          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
-          children: [
-            wSport(
-                '${_model.stepCount.value}', 'assets/images/ic_step_count.png',
-                textStyle: style),
-            wSport(_model.kCal.value.toStringAsFixed(1),
-                'assets/images/ic_kcal.png',
-                textStyle: style),
-            wSport(
-                _model.ck.value.toStringAsFixed(1), 'assets/images/ic_ck.png',
-                textStyle: style),
-            wSport(_model.ei.round().toString(), 'assets/images/ic_ei.png',
-                textStyle: style),
-          ],
-        ));
-  }
-
-  Widget _bottomBar() {
-    return Obx(() => Padding(
-        padding: const EdgeInsets.only(bottom: 20, left: 20, right: 20),
-        child: Row(
-          mainAxisAlignment: MainAxisAlignment.spaceBetween,
-          crossAxisAlignment: CrossAxisAlignment.end,
-          children: [
-            GestureDetector(
-                onTap: _onSetMapScale,
-                child: Image.asset('assets/images/btn_ruler_scale_no_map.png',
-                  width: 46,
-                )),
-            SizedBox(
-                width: 56,
-                height: 56,
-                child: ButtonPunch(
-                    onPressed: controller.isCheckCPButtonEnable
-                        ? controller.onCheckControlPoint
-                        : null,
-                  isWarn: controller.isCheckCPButtonWarn,
-                )),
-            GestureDetector(
-                onTap: () => controller.isNoMapRulerScaleMode.value = true,
-                child: Image.asset(
-                  'assets/images/btn_ruler_no_map.png',
-                  width: 46,
-                ))
-          ],
-        )));
-  }
-  Widget _topButton({required VoidCallback onPressed, required String src}){
-    return GestureDetector(
-      onTap: onPressed,
-      child: Image.asset(
-        src,
-        width: 34,
-        height: 34,
-      )
-    );
-  }
-  Widget _topButtonBar() {
-    return Row(
-      mainAxisAlignment: MainAxisAlignment.spaceBetween,
-      children: [
-        _topButton(
-          onPressed: () => Get.to(() => InfoView()),
-           src: 'assets/images/btn_info_no_map.png'
-        ),
-        _topButton(
-            onPressed: (){},
-            // showCheckedPoints,
-            src: 'assets/images/btn_past_cp_no_map.png'
-        ),
-        _topButton(
-            onPressed: _onBrightness,
-            src: 'assets/images/btn_brightness_no_map.png'
-        ),
-        _topButton(
-            onPressed: controller.toSettings,
-            src: 'assets/images/btn_settings_no_map.png'
-        ),
-        _topButton(
-            onPressed: ()=>onButtonExit(controller),
-            src: 'assets/images/btn_exit_no_map.png'
-        ),
-      ],
-    );
-  }
-  void _onBrightness()async{
-    await controller.setIsBrightnessMax(!controller.isBrightnessMax);
-  }
-
-  _onSetMapScale() {
-    var value = controller.mapScale.value?.toString() ?? '';
-
-    Get.dialog(AlertDialog(
-      title: const Text('设置比例尺'),
-      content: Row(
-        children: [
-          const Text(
-            '1 :',
-            style: TextStyle(fontSize: 16),
-          ),
-          const SizedBox(
-            width: 6,
-          ),
-          SizedBox(
-              width: 120,
-              child: TextField(
-                  onChanged: (v) {
-                    value = v;
-                  },
-                  keyboardType: TextInputType.number,
-                  controller: TextEditingController.fromValue(
-                      TextEditingValue(text: value)))),
-        ],
-      ),
-      actions: [
-        TextButton(
-            onPressed: () {
-              Get.back();
-            },
-            child: const Text('取消')),
-        TextButton(
-            onPressed: () {
-              controller.mapScale.value = double.tryParse(value);
-              Get.back();
-            },
-            child: const Text('确定')),
-      ],
-    ));
-  }
-}
-
-class _Elem extends StatelessWidget {
-  const _Elem({required this.child});
-
-  final Widget child;
-
-  @override
-  Widget build(BuildContext context) {
-    return Expanded(
-        child: Container(
-      height: 55,
-      alignment: Alignment.center,
-      decoration: BoxDecoration(
-          color: const Color(0x29ffffff),
-          border: Border.all(color: const Color(0x43ffffff), width: 1.09),
-          borderRadius: BorderRadius.circular(2.18)),
-      child: child,
-    ));
-  }
-}
-
-class _Home extends StatelessWidget {
-  @override
-  Widget build(BuildContext context) {
-    return InGameNoMapView();
-  }
-}
-
-void main() async {
-  Mock.initServices();
-  await App.to.init();
-  Get.put(GameModel());
-  Get.put(GameService());
-  await GameService.to.gameStart();
-  // await GameService.to.gameLoad();
-
-  var c = InGameControllerMock();
-  Get.put<InGameController>(c);
-
-  runApp(GetMaterialApp(
-      theme: ThemeData(useMaterial3: true, colorScheme: lightColorScheme),
-      home: _Home()));
-}

+ 0 - 75
lib/view/ingame/in_game_view.dart

@@ -1,75 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:get/get.dart';
-import 'package:trackoffical_app/service/game/game_model.dart';
-import 'package:trackoffical_app/service/user_profile.dart';
-import 'package:trackoffical_app/view/ingame/layer_cp_touch.dart';
-import 'package:trackoffical_app/view/ingame/layer_map.dart';
-import '../../service/game/game.dart';
-import 'package:trackoffical_app/widget/will_exit_after_2_back.dart';
-import '../../service/app.dart';
-import '../../service/mock.dart';
-import './in_game_controller.dart';
-import '../../styles/color_schemes.g.dart';
-import 'in_game_no_map_view.dart';
-import 'layer_front_ui.dart';
-import 'layer_warn.dart';
-
-class InGameView extends GetView<InGameController> {
-  const InGameView({super.key});
-
-  static Bindings bindings() {
-    return BindingsBuilder(() {
-      Get.lazyPut<InGameController>(() => InGameController());
-    });
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    return WillExitAfter2Back(
-        child: Obx(() => controller.uiMode.value!=GameUIMode.electronicMap? InGameNoMapView(): Scaffold(
-          backgroundColor: const Color(0xffd6d6d6),
-          body: Stack(
-            children: [
-              const LayerMap(),
-              const LayerWarn(),
-              _LayerMapTouch(),
-              const LayerCPTouch(),
-              LayerFrontUI(),
-            ],
-          ),
-        ))  );
-  }
-}
-
-
-class _LayerMapTouch extends GetView<GameService> {
-  @override
-  Widget build(BuildContext context) {
-    return GestureDetector(
-      onScaleStart: (v) => controller.mapStatus.onMapTouchScaleStart(v),
-      onScaleUpdate: (v) => controller.mapStatus
-          .onMapTouchScaleUpdate(v, Size(context.width, context.height)),
-      onScaleEnd: (v) => controller.mapStatus.isTouching = false,
-      child: SizedBox.expand(
-        child: Container(color: Colors.transparent),
-      ),
-    );
-  }
-}
-
-
-void main() async {
-  Mock.initServices();
-  await App.to.init();
-  Get.put(GameModel());
-  Get.put(GameService());
-  await GameService.to.gameStart();
-  // await GameService.to.gameLoad();
-
-  var c = InGameControllerMock();
-  Get.put<InGameController>(c);
-
-  runApp(GetMaterialApp(
-      theme: ThemeData(useMaterial3: true, colorScheme: lightColorScheme),
-      home: const InGameView()));
-}

+ 0 - 61
lib/view/ingame/info_view.dart

@@ -1,61 +0,0 @@
-import 'package:get/get.dart';
-import '../../widget/app_net_image.dart';
-import 'in_game_controller.dart';
-import 'package:flutter/material.dart';
-import 'package:webview_flutter/webview_flutter.dart';
-
-class InfoView extends GetView<InGameController>{
-  late final WebViewController wc;
-
-  InfoView({super.key}){
-
-    wc = WebViewController()
-      ..setJavaScriptMode(JavaScriptMode.unrestricted)
-      ..setBackgroundColor(const Color(0x00000000))
-      ..setNavigationDelegate(
-        NavigationDelegate(
-          onProgress: (int progress) {
-            // Update loading bar.
-          },
-          onPageStarted: (String url) {},
-          onPageFinished: (String url) {},
-          onWebResourceError: (WebResourceError error) {},
-          // onNavigationRequest: (NavigationRequest request) {
-          //   if (request.url.startsWith('https://www.youtube.com/')) {
-          //     return NavigationDecision.prevent;
-          //   }
-          //   return NavigationDecision.navigate;
-          // },
-        ),
-      )
-      ..loadRequest(Uri.parse('https://www.beswell.com/info/info.html'));
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    return DefaultTabController(
-      initialIndex: 0,
-      length: 2,
-      child: Scaffold(
-        appBar: AppBar(
-          title: const Text(''),
-          bottom:const  TabBar(tabs: [
-            Tab(text: '帮助'),
-            Tab(text: '图例')
-          ]),
-        ),
-        body: TabBarView(
-          physics: const NeverScrollableScrollPhysics(),
-          children: [
-            WebViewWidget(controller: wc),
-            AppNetImage(
-              netImage: controller.legend,
-              fit: BoxFit.contain,
-            )
-          ],
-        )    ,
-      )
-    );
-  }
-
-}

+ 0 - 56
lib/view/ingame/instance_view.dart

@@ -1,56 +0,0 @@
-import 'package:trackoffical_app/service/game/game_instance.dart';
-import 'package:flutter/material.dart';
-export 'package:flutter/material.dart';
-import 'package:get/get.dart';
-import 'in_game_loading2.dart';
-
-class InstanceView extends StatefulWidget{
-  const InstanceView({
-    super.key,
-    this.closingView,
-    required this.instance,
-    required this.child});
-
-  final GameInstance instance;
-  final Widget child;
-  final Widget? closingView;
-
-  @override
-  State<StatefulWidget> createState() {
-    return _InstanceState();
-  }
-}
-
-class _InstanceState extends State<InstanceView>{
-  final state = GameInstanceState.uninitialized.obs;
-  @override
-  void initState() {
-    state.value=widget.instance.state;
-    state.bindStream(widget.instance.stateStream);
-    super.initState();
-  }
-  @override
-  void dispose() {
-    state.close();
-    super.dispose();
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    final instance = widget.instance;
-    return Obx((){
-      switch(state.value){
-        case GameInstanceState.uninitialized:
-          return InGameLoadingView(instance: instance);
-        case GameInstanceState.initialized:
-          return widget.child;
-        case GameInstanceState.closing:
-        case GameInstanceState.closed:
-          return widget.closingView??widget.child;
-      }
-    });
-  }
-
-
-}
-

+ 0 - 29
lib/view/ingame/layer/layer.dart

@@ -1,29 +0,0 @@
-import 'layer_controller.dart';
-export 'layer_controller.dart';
-
-abstract class LayerView<T> extends GetView<LayerController>{
-  const LayerView({super.key});
-
-  @protected
-  T get viewModel => controller as T;
-}
-class Layer extends StatelessWidget{
-  const Layer({
-    super.key,
-    required this.children
-  });
-
-  final List<Widget> children;
-
-  @override
-  Widget build(BuildContext context) {
-    return SizedBox(
-        width: context.width, height: context.height,
-        child: Stack(
-        alignment: Alignment.topLeft,
-        children: children
-    )
-    ) ;
-  }
-
-}

+ 0 - 298
lib/view/ingame/layer/layer_controller.dart

@@ -1,298 +0,0 @@
-import 'dart:async';
-import 'dart:math';
-import 'package:get/get.dart';
-import 'package:flutter/material.dart';
-import 'package:get_storage/get_storage.dart';
-import 'package:trackoffical_app/model.dart';
-import '../../../model/game_map.dart';
-import '../../../service/app.dart';
-export 'package:get/get.dart';
-export 'dart:typed_data';
-export 'package:flutter/material.dart';
-
-
-abstract class LayerController extends GetxController
-    with GetSingleTickerProviderStateMixin{
-
-  GameMap? get gameMap;
-  final mapTransformMatrix = Matrix4.identity().obs;
-  Rx<Size?> mapWidgetSize = Rx(null);
-  final mapWidgetKey = GlobalKey();
-  Timer? _mapWidgetSizeTimer;
-  double _mapScreenAndSrcScale = 1;
-  final mapRotateCenter = Offset.zero.obs;
-  var isEnableUserTouchTranslation = true;
-  var isEnableUserTouchRotation = true;
-  final cpRadiusMeter = 15.0.obs;
-  // 比例尺  缩放后地图在屏幕的尺寸/米 实时
-  final _mapScale = 0.0.obs;
-  // 比例尺  屏幕尺寸/米 原始
-  var mapScaleSrc = 0.0;
-  var _isScaling = false;
-  bool get isWidgetInit => mapWidgetSize.value != null;
-  double get mapScale => _mapScale.value;
-  var _matrixScale=1.0;
-  var matrixRotation=0.0;
-
-  final _translationUpdater = _ValueUpdater<Offset>(
-    onUpdate: (oldVal, newVal) => newVal - (oldVal ?? Offset.zero),
-  );
-  final _rotationUpdater = _ValueUpdater<double>(
-    onUpdate: (oldVal, newVal) => newVal - (oldVal ?? 0),
-  );
-  final _scaleUpdater = _ValueUpdater<double>(
-    onUpdate: (oldVal, newVal) => newVal / (oldVal ?? 1),
-  );
-  var scaleMax = 9.0;
-  var scaleMin = 1.0;
-
-  void onMapSizeChange(Size size){
-    final map = gameMap;
-    if(map!= null){
-      final fitted = applyBoxFit(
-          BoxFit.contain,
-          Size(map.width, map.height),
-          Size(size.width, size.height));
-
-      _mapScreenAndSrcScale = fitted.destination.width / fitted.source.width;
-
-      final screenLen = size.width;
-      mapScaleSrc = screenLen / map.mapWidth.m;
-
-      calculateMapScale();
-    }
-  }
-
-  Offset mapOffsetToScreen(Offset offset){
-    var thisOffset = Offset(offset.dx * _mapScreenAndSrcScale, offset.dy * _mapScreenAndSrcScale);
-    final mr= mapTransformMatrix.value.applyToVector3Array([thisOffset.dx, thisOffset.dy, 0]);
-    return Offset(mr[0], mr[1]);
-  }
-  Future<Offset> positionToScreen(MPosition position)async{
-    final g = gameMap;
-    if(g==null){
-      return Offset.zero;
-    }
-    final offset = await g.worldToPixel(position);
-    return mapOffsetToScreen(offset);
-  }
-  void setRotate(double radians){
-    if(_isScaling){
-      return;
-    }
-    if(!isWidgetInit){
-      return;
-    }
-    if(mapRotateCenter.value==Offset.zero){
-      return;
-    }
-
-
-    final rotate =  _getRotationMatrix(radians);
-    mapTransformMatrix.value = rotate * mapTransformMatrix.value;
-    // final focalPoint = mapRotateCenter.value;
-    // if(focalPoint != Offset.zero){
-    //   final rotate =  _getRotationMatrix(radians);
-    //   if(rotate!= null){
-    //     var matrix = mapTransformMatrix.value;
-    //     mapTransformMatrix.value = rotate * matrix;
-    //   }
-    // }
-  }
-
-  void moveOnMapPointToScreen(Offset src, Offset dst){
-    final pOnScreen =  mapOffsetToScreen(src);
-    final dis = dst - pOnScreen;
-    final tranM = Matrix4.translationValues(dis.dx, dis.dy, 0);
-    mapTransformMatrix.value = tranM * mapTransformMatrix.value;
-  }
-  double meterToOnScreen(double meter){
-    return meter * _mapScale.value;
-  }
-
-
-  calculateMapScale(){
-    final gameMap = this.gameMap;
-    if(gameMap==null){
-      return;
-    }
-
-    const p0Src = Offset(0, 0);
-    final p1Src = Offset(gameMap.width, 0);
-
-    final p0Dst = mapOffsetToScreen(p0Src);
-    final p1Dst = mapOffsetToScreen(p1Src);
-
-    final disPx = sqrt((p1Dst.dx - p0Dst.dx)* (p1Dst.dx - p0Dst.dx)
-        + (p1Dst.dy - p0Dst.dy) * (p1Dst.dy - p0Dst.dy));
-
-    _mapScale.value = disPx / gameMap.mapWidth.m;
-  }
-
-  void onMapTouchScaleStart(ScaleStartDetails details) {
-    _translationUpdater.value = details.focalPoint;
-    _rotationUpdater.value = double.nan;
-    _scaleUpdater.value = 1.0;
-    _isScaling=true;
-  }
-  void onMapTouchScaleEnd(ScaleEndDetails details) {
-    _isScaling=false;
-  }
-  void onMapTouchScaleUpdate(ScaleUpdateDetails details) {
-
-    var matrix = mapTransformMatrix.value.clone();
-
-
-
-    // 平移
-    if(isEnableUserTouchTranslation){
-      final translationDelta = _translationUpdater.update(details.focalPoint);
-      final translationDeltaMatrix =
-      Matrix4.translationValues(translationDelta.dx, translationDelta.dy, 0);
-      matrix = translationDeltaMatrix * matrix;
-    }
-
-
-
-    // 旋转
-    if(isEnableUserTouchRotation){
-      if (_rotationUpdater.value == null || _rotationUpdater.value!.isNaN) {
-        _rotationUpdater.value = details.rotation;
-      } else{
-        final rotationDelta = _rotationUpdater.update(details.rotation);
-        final radians = rotationDelta+matrixRotation;
-        final rotationDeltaMatrix = _getRotationMatrix(radians);
-        matrix = rotationDeltaMatrix * matrix;
-      }
-    }
-
-    // 缩放
-    final scaleDelta = _scaleUpdater.update(details.scale);
-    matrix = _doScaleLimit(scaleDelta, matrix);
-
-    mapTransformMatrix.value = matrix;
-    calculateMapScale();
-  }
-  void mapDoScale(double value){
-    mapTransformMatrix.value = _doScaleLimit(value, mapTransformMatrix.value);
-    calculateMapScale();
-  }
-  void resetMatrix(){
-    mapTransformMatrix.value = Matrix4.identity();
-    _rotationUpdater.value = 0;
-    _translationUpdater.value = Offset.zero;
-    _scaleUpdater.value = 1;
-    _matrixScale=1;
-    matrixRotation=0;
-
-    calculateMapScale();
-  }
-
-  Matrix4 _getRotationMatrix(double radians){
-    final delta = radians - matrixRotation;
-
-    var c = cos(delta);
-    var s = sin(delta);
-    var dx = (1 - c) * mapRotateCenter.value.dx + s * mapRotateCenter.value.dy;
-    var dy = (1 - c) * mapRotateCenter.value.dy - s * mapRotateCenter.value.dx;
-    final rotationDeltaMatrix = Matrix4(
-        c,  s,  0,  0,
-        -s, c,  0,  0,
-        0,  0,  1,  0,
-        dx, dy, 0,  1);
-
-    matrixRotation=radians;
-    return rotationDeltaMatrix;
-  }
-
-  @override
-  void onReady() {
-    super.onReady();
-
-    _mapWidgetSizeTimer = Timer.periodic(20.milliseconds, (timer) {
-      final renderBox = mapWidgetKey.currentContext?.findRenderObject()  as RenderBox?;
-      if(renderBox!= null){
-        final size = renderBox.size;
-        if(size != Size.zero && size != mapWidgetSize.value){
-          mapWidgetSize.value = size;
-          onMapSizeChange(size);
-        }
-      }
-    });
-  }
-
-  @override
-  void onClose() {
-    super.onClose();
-    _mapWidgetSizeTimer?.cancel();
-  }
-
-  Matrix4 _doScaleLimit(double scaleDelta, Matrix4 matrix){
-    var scale = _matrixScale*scaleDelta;
-    var delta = scaleDelta;
-    if(scale < scaleMin){
-      delta = scaleMin / scale;
-    }
-    if( scale > scaleMax){
-      delta = scaleMax / scale;
-    }
-
-
-    return _doScale(delta, matrix);
-  }
-
-  Matrix4 _doScale(double scaleDelta, Matrix4 matrix){
-    // matrix = matrix.clone();
-    // final centerSrc = <double>[mapRotateCenter.value.dx,mapRotateCenter.value.dy,0];
-    // final ma = matrix.clone();
-    // ma.invert();
-    // final center = ma.applyToVector3Array(centerSrc.toList());
-    //
-    // matrix.translate(center[0], center[1]);
-    // matrix.scale(scaleDelta, scaleDelta);
-    // matrix.translate(-center[0], -center[1]);
-    // _matrixScale*=scaleDelta;
-    // return matrix;
-    var dx = (1 - scaleDelta) * mapRotateCenter.value.dx;
-    var dy = (1 - scaleDelta) * mapRotateCenter.value.dy;
-    final scaleDeltaMatrix = Matrix4(
-        scaleDelta, 0, 0, 0,
-        0, scaleDelta, 0, 0,
-        0, 0, 1, 0,
-        dx, dy, 0, 1);
-    _matrixScale*=scaleDelta;
-    return scaleDeltaMatrix * matrix;
-  }
-
-}
-
-
-
-typedef _OnUpdate<T> = T Function(T? oldValue, T newValue);
-
-class _ValueUpdater<T> {
-  final _OnUpdate<T> onUpdate;
-  T? value;
-
-  _ValueUpdater({required this.onUpdate});
-
-  T update(T newValue) {
-    T updated = onUpdate(value, newValue);
-    value = newValue;
-    return updated;
-  }
-}
-
-class StorageRx<T>{
-  StorageRx(this._data): _state=_data.val.obs;
-
-  final ReadWriteValue<T> _data;
-  final Rx<T> _state;
-
-  T get value => _state.value;
-  set value(T v){
-    _state.value = v;
-    _data.val = v;
-  }
-}
-

Некоторые файлы не были показаны из-за большого количества измененных файлов