| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- import 'dart:async';
- import 'package:get/get.dart';
- import 'package:grpc/grpc.dart';
- import 'package:trackoffical_app/service/api.dart';
- import 'package:trackoffical_app/service/app.dart';
- import 'package:trackoffical_app/utils.dart';
- import '../../../logger.dart';
- import '../plug.dart';
- import 'game_instance_std.dart';
- class PlugLocation extends Plug{
- PlugLocation(GameInstanceStd ins){
- instance=ins;
- final lastInfo = ins.model.gameSrcState.value.pbGameSave.gameGpsInfos;
- if(lastInfo.isNotEmpty){
- for(var one in lastInfo){
- var p = MPosition();
- p.latitude = one.latitude;
- p.longitude = one.longitude;
- p.directionRadian = one.directionRadian;
- p.timestamp = one.gpsTime.toModel();
- _addOnePosition(p, false);
- }
- }
- }
- GameInstanceStd? instance;
- final _app = App.to;
- final _api = ApiService.to;
- final _toUpload = <MPosition>[];
- bool get isEnableGPSTrack => _app.userProfile.gameSettingsGpsTrack.value;
- Future<void> uploadPosition() async {
- final ins = instance;
- if(ins!= null && isEnableGPSTrack){
- final model = ins.model;
- final gameId = model.gameSrcState.value.pbGameData.gameId;
- final data = <MPosition>[];
- final distanceMeter = model.myPositionHistoryLen.value.m;
- final paceSecondKm = model.paceSecondKm;
- if(_toUpload.isNotEmpty){
- data.addAll(_toUpload);
- try {
- await _api.gameGpsUpload(
- gameId, data, distanceMeter.round(), paceSecondKm.value.inSeconds);
- _toUpload.clear();
- } catch (e) {
- warn('GameId[$gameId]上传位置失败: $e');
- }
- }
- }
- }
- void onRcvPosition(MPosition p, GameInstanceStd ins) {
- p.directionRadian = -ins.compassRadiansFused.value;
- _toUpload.add(p);
- _addOnePosition(p, true);
- }
- void _addOnePosition(MPosition p, bool isSaveToDB){
- final ins = instance;
- if(ins==null){
- return;
- }
- MPosition? last;
- if (ins.model.myPositionHistory.isNotEmpty) {
- last = ins.model.myPositionHistory.last;
- }
- ins.model.myPositionHistory.add(p);
- ins.gameMapData.worldToPixel(p).then((offset){
- ins.model.myPositionOnMapHistory.add(offset);
- });
- ins.gameMapData.mapPackage?.isInHotZone(p).then((value) =>
- ins.model.zone.value=value
- );
- final startAt=ins.model.startAt;
- if(startAt==null){
- return;
- }
- final endAt = ins.model.endAt;
- if(endAt != null){
- if(p.timestamp.isAfter(endAt)){
- return;
- }
- }
- if(p.timestamp.isBefore(startAt)){
- return;
- }
- // 只记录开始点后
- if (last!=null) {
- final dis = p.distance(last);
- ins.model.myPositionHistoryLen.value += dis;
- }
- if(isSaveToDB){
- ins.model.gameSrcState.value.pbGameSave.gameGpsInfos.add(p.toPb2());
- }
- }
- Future<void> loopUploadPosition() async {
- while (isActive) {
- await Future.delayed(1.seconds);
- await uploadPosition();
- }
- }
- Future<void> _makeSureUploadAll() async {
- while (true) {
- try {
- await uploadPosition();
- return;
- } on GrpcError catch (e) {
- if (e.code != StatusCode.unavailable) {
- return;
- }
- error(e);
- } catch (e) {
- error(e);
- return;
- }
- await Future.delayed(100.milliseconds);
- }
- }
- @override
- Future<void> init() async{
- final locationStream = _app.locationStream;
- listenStream(locationStream, (p) {
- final ins = instance;
- if(ins!= null){
- onRcvPosition(p, ins);
- }
- });
- _app.locationStart(500.milliseconds, 1);
- _app.getPosition(timeout: 5.seconds).then((p) {
- final ins = instance;
- if(ins!= null){
- onRcvPosition(p, ins);
- }
- });
- loopUploadPosition();
- }
- @override
- Future<void> onClose() async{
- _app.locationStop();
- await _makeSureUploadAll();
- instance=null;
- }
- }
|