Project

General

Profile

Download (18.7 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / main_old / RubikObjectLibInterface.java @ 1c04d054

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9

    
10
package org.distorted.main_old;
11

    
12
import android.os.Bundle;
13

    
14
import androidx.annotation.NonNull;
15

    
16
import com.google.android.play.core.review.ReviewInfo;
17
import com.google.android.play.core.review.ReviewManager;
18
import com.google.android.play.core.review.ReviewManagerFactory;
19
import com.google.android.play.core.tasks.OnCompleteListener;
20
import com.google.android.play.core.tasks.OnFailureListener;
21
import com.google.android.play.core.tasks.Task;
22
import com.google.firebase.analytics.FirebaseAnalytics;
23
import com.google.firebase.crashlytics.FirebaseCrashlytics;
24

    
25
import org.distorted.dialogs.RubikDialogScoresView;
26
import org.distorted.library.main.DistortedScreen;
27
import org.distorted.library.message.EffectMessageSender;
28

    
29
import org.distorted.external.RubikNetwork;
30
import org.distorted.main.BuildConfig;
31
import org.distorted.objectlib.helpers.BlockController;
32
import org.distorted.objectlib.helpers.ObjectLibInterface;
33
import org.distorted.objectlib.main.ObjectControl;
34

    
35
import org.distorted.dialogs.RubikDialogNewRecord;
36
import org.distorted.dialogs.RubikDialogSolved;
37
import org.distorted.external.RubikScores;
38
import org.distorted.objects.RubikObject;
39
import org.distorted.objects.RubikObjectList;
40
import org.distorted.overlays.DataStars;
41
import org.distorted.overlays.ListenerOverlay;
42
import org.distorted.overlays.OverlayStars;
43
import org.distorted.screens.RubikScreenPlay;
44
import org.distorted.screens.RubikScreenReady;
45
import org.distorted.screens.RubikScreenSolver;
46
import org.distorted.screens.RubikScreenSolving;
47
import org.distorted.screens.ScreenList;
48
import org.distorted.solvers.SolverMain;
49

    
50
import java.lang.ref.WeakReference;
51

    
52
import static org.distorted.external.RubikScores.RECORD_FIRST;
53
import static org.distorted.external.RubikScores.RECORD_NEW;
54
import static org.distorted.external.RubikScores.RECORD_NOT_NEW;
55

    
56
///////////////////////////////////////////////////////////////////////////////////////////////////
57

    
58
public class RubikObjectLibInterface implements ObjectLibInterface, ListenerOverlay
59
{
60
  private final WeakReference<RubikActivity> mAct;
61
  private int mIsNewRecord;
62
  private int mNewRecord;
63
  private int mLastCubitColor, mLastCubit, mLastCubitFace;
64
  private boolean mReviewAsked;
65
  private int mNumRotations, mNumScrambles;
66

    
67
///////////////////////////////////////////////////////////////////////////////////////////////////
68

    
69
  RubikObjectLibInterface(RubikActivity act)
70
    {
71
    mAct = new WeakReference<>(act);
72
    mLastCubitColor = -1;
73
    mReviewAsked = false;
74
    mNumRotations = 0;
75
    mNumScrambles = 0;
76
    }
77

    
78
///////////////////////////////////////////////////////////////////////////////////////////////////
79

    
80
  private void analyticsReport(RubikActivity act, String message, String name, long timeBegin)
81
    {
82
    long elapsed = System.currentTimeMillis() - timeBegin;
83
    String msg = message+" startTime: "+timeBegin+" elapsed: "+elapsed+" name: "+name;
84

    
85
    if( BuildConfig.DEBUG )
86
       {
87
       android.util.Log.d("libInterface", msg);
88
       }
89
    else
90
      {
91
      FirebaseAnalytics analytics = act.getAnalytics();
92

    
93
      if( analytics!=null )
94
        {
95
        Bundle bundle = new Bundle();
96
        bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, msg);
97
        analytics.logEvent(FirebaseAnalytics.Event.SHARE, bundle);
98
        }
99
      }
100
    }
101

    
102
///////////////////////////////////////////////////////////////////////////////////////////////////
103

    
104
  private void reportRecord(RubikActivity act, long startTime, long endTime, String debug, int scrambleNum)
105
    {
106
    RubikScreenPlay play= (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
107
    RubikScores scores  = RubikScores.getInstance();
108
    int object  = RubikObjectList.getCurrObject();
109
    int level   = play.getLevel();
110
    String name = scores.getName();
111
    RubikObject obj = RubikObjectList.getObject(object);
112
    String objName = obj==null ? "NULL" : obj.getUpperName();
113

    
114
    String record = objName+" level "+level+" time "+mNewRecord+" isNew: "+mIsNewRecord+" scrambleNum: "+scrambleNum;
115

    
116
    if( BuildConfig.DEBUG )
117
       {
118
       android.util.Log.e("libInterface", debug);
119
       android.util.Log.e("libInterface", name);
120
       android.util.Log.e("libInterface", record);
121
       }
122
    else
123
      {
124
      if( level>=9 && mNewRecord<300*level )
125
        {
126
        long timeNow = System.currentTimeMillis();
127
        long elapsed = timeNow - startTime;
128
        String suspicious ="start"+startTime+"end"+endTime+"elapsed"+elapsed+"obj"+objName+"level"+level+"record"+mNewRecord+"scrambles"+scrambleNum+debug;
129
        RubikNetwork network = RubikNetwork.getInstance();
130
        network.suspicious(suspicious,act);
131
        }
132

    
133
      FirebaseAnalytics analytics = act.getAnalytics();
134

    
135
      if( analytics!=null )
136
        {
137
        Bundle bundle = new Bundle();
138
        bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, debug);
139
        bundle.putString(FirebaseAnalytics.Param.CHARACTER, name);
140
        bundle.putString(FirebaseAnalytics.Param.LEVEL, record);
141
        analytics.logEvent(FirebaseAnalytics.Event.LEVEL_UP, bundle);
142
        }
143
      }
144
    }
145

    
146
///////////////////////////////////////////////////////////////////////////////////////////////////
147

    
148
  private Bundle createDialogBundle()
149
    {
150
    Bundle bundle = new Bundle();
151
    String arg = RubikDialogScoresView.formatRecord(mNewRecord);
152
    bundle.putString("argument", arg );
153
    return bundle;
154
    }
155

    
156
///////////////////////////////////////////////////////////////////////////////////////////////////
157

    
158
  private void requestReview(RubikActivity act)
159
    {
160
    android.util.Log.e("D", "ASKING FOR REVIEW");
161

    
162
    mReviewAsked = true;
163
    final String name = RubikScores.getInstance().getName();
164
    final long timeBegin = System.currentTimeMillis();
165
    final ReviewManager manager = ReviewManagerFactory.create(act);
166
    Task<ReviewInfo> request = manager.requestReviewFlow();
167

    
168
    request.addOnCompleteListener(new OnCompleteListener<ReviewInfo>()
169
      {
170
      @Override
171
      public void onComplete (@NonNull Task<ReviewInfo> task)
172
        {
173
        if (task.isSuccessful())
174
          {
175
          ReviewInfo reviewInfo = task.getResult();
176
          Task<Void> flow = manager.launchReviewFlow(act, reviewInfo);
177

    
178
          flow.addOnFailureListener(new OnFailureListener()
179
            {
180
            @Override
181
            public void onFailure(Exception e)
182
              {
183
              analyticsReport(act,"Failed", name, timeBegin);
184
              }
185
            });
186

    
187
          flow.addOnCompleteListener(new OnCompleteListener<Void>()
188
            {
189
            @Override
190
            public void onComplete(@NonNull Task<Void> task)
191
              {
192
              analyticsReport(act,"Complete", name, timeBegin);
193
              }
194
            });
195
          }
196
        else analyticsReport(act,"Not Successful", name, timeBegin);
197
        }
198
      });
199
    }
200

    
201
///////////////////////////////////////////////////////////////////////////////////////////////////
202

    
203
  public void onScrambleEffectFinished()
204
    {
205
    RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
206

    
207
    if( play.shouldReactToEndOfScrambling() )
208
      {
209
      RubikActivity act = mAct.get();
210
      RubikScores.getInstance().incrementNumPlays();
211

    
212
      act.runOnUiThread(new Runnable()
213
        {
214
        @Override
215
        public void run()
216
          {
217
          ScreenList.switchScreen( act, ScreenList.READ);
218
          ObjectControl control = act.getControl();
219
          control.unblockEverything();
220
          }
221
        });
222
      }
223
    else
224
      {
225
      mNumScrambles++;
226

    
227
      if( mNumScrambles==10 && !mReviewAsked )
228
        {
229
        RubikActivity act = mAct.get();
230
        requestReview(act);
231
        }
232
      }
233
    }
234

    
235
///////////////////////////////////////////////////////////////////////////////////////////////////
236

    
237
  public void onFinishRotation(int axis, int row, int angle)
238
    {
239
    mNumRotations++;
240

    
241
    if( ScreenList.getCurrentScreen()== ScreenList.SOLV )
242
      {
243
      RubikScreenSolving solv = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
244
      solv.addMove(mAct.get(), axis, row, angle);
245
      }
246
    if( ScreenList.getCurrentScreen()== ScreenList.PLAY )
247
      {
248
      RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
249
      play.addMove(mAct.get(), axis, row, angle);
250
      }
251

    
252
    if( mNumRotations==40 && !mReviewAsked )
253
      {
254
      RubikActivity act = mAct.get();
255
      requestReview(act);
256
      }
257
    }
258

    
259
///////////////////////////////////////////////////////////////////////////////////////////////////
260

    
261
  public void onBeginRotation()
262
    {
263
    if( ScreenList.getCurrentScreen()== ScreenList.READ )
264
      {
265
      RubikScreenSolving solving = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
266
      solving.resetElapsed();
267
      RubikActivity act = mAct.get();
268

    
269
      act.runOnUiThread(new Runnable()
270
        {
271
        @Override
272
        public void run()
273
          {
274
          ScreenList.switchScreen( act, ScreenList.SOLV);
275
          }
276
        });
277
      }
278
    }
279

    
280
///////////////////////////////////////////////////////////////////////////////////////////////////
281

    
282
  public void failedToDrag()
283
    {
284
    ScreenList curr = ScreenList.getCurrentScreen();
285

    
286
    if( curr==ScreenList.PLAY )
287
      {
288
      RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
289
      play.reddenLock(mAct.get());
290
      }
291
    else if( curr==ScreenList.READ )
292
      {
293
      RubikScreenReady read = (RubikScreenReady) ScreenList.READ.getScreenClass();
294
      read.reddenLock(mAct.get());
295
      }
296
    else if( curr==ScreenList.SOLV )
297
      {
298
      RubikScreenSolving solv = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
299
      solv.reddenLock(mAct.get());
300
      }
301
    }
302

    
303
///////////////////////////////////////////////////////////////////////////////////////////////////
304

    
305
  public void onSolved()
306
    {
307
    if( ScreenList.getCurrentScreen()== ScreenList.SOLV )
308
      {
309
      RubikScreenSolving solving = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
310
      mNewRecord = solving.stopTimerAndGetRecord();
311
      mIsNewRecord = solving.setRecord();
312
      }
313
    }
314

    
315
///////////////////////////////////////////////////////////////////////////////////////////////////
316

    
317
  public void onObjectCreated(long time)
318
    {
319

    
320
    }
321

    
322
///////////////////////////////////////////////////////////////////////////////////////////////////
323

    
324
  public void reportProblem(String problem, boolean recordException)
325
    {
326
    if( BuildConfig.DEBUG )
327
      {
328
      android.util.Log.e("libInterface", problem);
329
      }
330
    else
331
      {
332
      if( recordException )
333
        {
334
        Exception ex = new Exception(problem);
335
        FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
336
        crashlytics.setCustomKey("problem" , problem);
337
        crashlytics.recordException(ex);
338
        }
339
      else
340
        {
341
        FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
342
        crashlytics.log(problem);
343
        }
344
      }
345
    }
346

    
347
///////////////////////////////////////////////////////////////////////////////////////////////////
348

    
349
  private void reportScramblingProblem(int place, long pause, long resume, long time)
350
    {
351
    String error = "SCRAMBLING BLOCK "+place+" blocked for "+time;
352

    
353
    if( BuildConfig.DEBUG )
354
       {
355
       android.util.Log.e("libInterface", error);
356
       }
357
    else
358
      {
359
      Exception ex = new Exception(error);
360
      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
361
      crashlytics.setCustomKey("pause" , pause );
362
      crashlytics.setCustomKey("resume", resume );
363
      crashlytics.recordException(ex);
364
      }
365
    }
366

    
367
///////////////////////////////////////////////////////////////////////////////////////////////////
368

    
369
  private void reportRotationProblem(int place, long pause, long resume, long time)
370
    {
371
    String error = "ROTATION BLOCK "+place+" blocked for "+time;
372

    
373
    if( BuildConfig.DEBUG )
374
       {
375
       android.util.Log.e("libInterface", error);
376
       }
377
    else
378
      {
379
      Exception ex = new Exception(error);
380
      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
381
      crashlytics.setCustomKey("pause" , pause );
382
      crashlytics.setCustomKey("resume", resume);
383
      crashlytics.recordException(ex);
384
      }
385
    }
386

    
387
///////////////////////////////////////////////////////////////////////////////////////////////////
388

    
389
  private void reportThreadProblem(int place, long pause, long resume, long time)
390
    {
391
    String error = EffectMessageSender.reportState();
392

    
393
    if( BuildConfig.DEBUG )
394
       {
395
       android.util.Log.e("libInterface", error);
396
       }
397
    else
398
      {
399
      Exception ex = new Exception(error);
400
      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
401
      crashlytics.setCustomKey("pause" , pause  );
402
      crashlytics.setCustomKey("resume", resume );
403
      crashlytics.recordException(ex);
404
      }
405
    }
406

    
407
///////////////////////////////////////////////////////////////////////////////////////////////////
408

    
409
  public void reportBlockProblem(int type, int place, long pause, long resume, long time)
410
    {
411
    switch(type)
412
      {
413
      case BlockController.TYPE_SCRAMBLING: reportScramblingProblem(place,pause,resume,time); break;
414
      case BlockController.TYPE_ROTATION  : reportRotationProblem(place,pause,resume,time); break;
415
      case BlockController.TYPE_THREAD    : reportThreadProblem(place,pause,resume,time); break;
416
      }
417
    }
418

    
419
///////////////////////////////////////////////////////////////////////////////////////////////////
420

    
421
  public void reportJSONError(String error, int ordinal)
422
    {
423
    RubikObject object = RubikObjectList.getObject(ordinal);
424
    String name = object==null ? "NULL" : object.getUpperName();
425

    
426
    if( BuildConfig.DEBUG )
427
       {
428
       android.util.Log.e("libInterface", "name="+name+" JSON error: "+error);
429
       }
430
    else
431
      {
432
      Exception ex = new Exception(error);
433
      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
434
      crashlytics.setCustomKey("name" , name );
435
      crashlytics.setCustomKey("JSONerror", error );
436
      crashlytics.recordException(ex);
437
      }
438
    }
439

    
440
///////////////////////////////////////////////////////////////////////////////////////////////////
441

    
442
  public void onReplaceModeDown(int cubit, int face)
443
    {
444
    RubikScreenSolver solver = (RubikScreenSolver) ScreenList.SVER.getScreenClass();
445
    int color = solver.getCurrentColor();
446
    int currObject = RubikObjectList.getCurrObject();
447
    mLastCubitColor = SolverMain.cubitIsLocked(currObject,cubit);
448
    mLastCubit = cubit;
449
    mLastCubitFace = face;
450
    ObjectControl control = mAct.get().getControl();
451
    control.setTextureMap( cubit, face, color );
452
    }
453

    
454
///////////////////////////////////////////////////////////////////////////////////////////////////
455

    
456
  public void onReplaceModeUp()
457
    {
458
    if( mLastCubitColor>=0 )
459
      {
460
      ObjectControl control = mAct.get().getControl();
461
      control.setTextureMap( mLastCubit, mLastCubitFace, mLastCubitColor );
462
      mLastCubitColor = -1;
463
      }
464
    }
465

    
466
///////////////////////////////////////////////////////////////////////////////////////////////////
467

    
468
  public void onWinEffectFinished(long startTime, long endTime, String debug, int scrambleNum)
469
    {
470
    if( ScreenList.getCurrentScreen()== ScreenList.SOLV )
471
      {
472
      RubikActivity act = mAct.get();
473
      reportRecord(act,startTime,endTime,debug,scrambleNum);
474

    
475
      RubikScores scores = RubikScores.getInstance();
476
      int numWins = scores.incrementNumWins();
477
      int numRuns = scores.getNumRuns();
478

    
479
      if( numRuns==3 || numRuns==6 || numWins==4 || numWins==20 || numWins==50 || numWins==80 || numWins==100)
480
        {
481
        requestReview(act);
482
        }
483

    
484
      switch(mIsNewRecord)
485
        {
486
        case RECORD_FIRST  : if( RubikActivity.USE_IAP )
487
                                {
488
                                RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
489
                                int level = play.getLevel();
490
                                int newStars = scores.computeNumStars(level);
491
                                int totStars = scores.getNumStars();
492
                                scores.changeNumStars(newStars);
493
                                DistortedScreen screen = act.getScreen();
494
                                OverlayStars stars = new OverlayStars();
495
                                DataStars data  = new DataStars(totStars,newStars,act.getResources());
496
                                stars.startOverlay(screen,this,data);
497
                                }
498
                             else
499
                                {
500
                                Bundle bundle = createDialogBundle();
501
                                RubikDialogNewRecord d2 = new RubikDialogNewRecord();
502
                                d2.setArguments(bundle);
503
                                d2.show( act.getSupportFragmentManager(), RubikDialogNewRecord.getDialogTag() );
504
                                }
505
                             break;
506
        case RECORD_NEW    : Bundle byes = createDialogBundle();
507
                             RubikDialogNewRecord dyes = new RubikDialogNewRecord();
508
                             dyes.setArguments(byes);
509
                             dyes.show( act.getSupportFragmentManager(), RubikDialogNewRecord.getDialogTag() );
510
                             break;
511
        case RECORD_NOT_NEW: Bundle bno = createDialogBundle();
512
                             RubikDialogSolved dno = new RubikDialogSolved();
513
                             dno.setArguments(bno);
514
                             dno.show( act.getSupportFragmentManager(), RubikDialogSolved.getDialogTag() );
515
                             break;
516
        }
517

    
518
      act.runOnUiThread(new Runnable()
519
        {
520
        @Override
521
        public void run()
522
          {
523
          ScreenList.switchScreen( act, ScreenList.DONE);
524
          }
525
        });
526
      }
527
    }
528

    
529
///////////////////////////////////////////////////////////////////////////////////////////////////
530

    
531
  public void overlayFinished(long id)
532
    {
533
    RubikActivity act = mAct.get();
534
    Bundle bundle = createDialogBundle();
535
    RubikDialogNewRecord d = new RubikDialogNewRecord();
536
    d.setArguments(bundle);
537
    d.show( act.getSupportFragmentManager(), RubikDialogNewRecord.getDialogTag() );
538
    }
539
}
(2-2/4)