Project

General

Profile

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

magiccube / src / main / java / org / distorted / main / RubikObjectLibInterface.java @ 240bf467

1 1cd323dd Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6 296219b4 Leszek Koltunski
// 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 1cd323dd Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
9
10
package org.distorted.main;
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 95472aca Leszek Koltunski
import com.google.firebase.crashlytics.FirebaseCrashlytics;
24 1cd323dd Leszek Koltunski
25 d7f0c07d Leszek Koltunski
import org.distorted.library.main.DistortedScreen;
26 95472aca Leszek Koltunski
import org.distorted.library.message.EffectMessageSender;
27 8723caee Leszek Koltunski
28 acabdd83 Leszek Koltunski
import org.distorted.external.RubikNetwork;
29 95472aca Leszek Koltunski
import org.distorted.objectlib.BuildConfig;
30
import org.distorted.objectlib.helpers.BlockController;
31 e019c70b Leszek Koltunski
import org.distorted.objectlib.helpers.ObjectLibInterface;
32 5c4ed8ed Leszek Koltunski
import org.distorted.objectlib.main.ObjectControl;
33 1cd323dd Leszek Koltunski
34
import org.distorted.dialogs.RubikDialogNewRecord;
35
import org.distorted.dialogs.RubikDialogSolved;
36 acabdd83 Leszek Koltunski
import org.distorted.external.RubikScores;
37 d433b50e Leszek Koltunski
import org.distorted.objects.RubikObject;
38
import org.distorted.objects.RubikObjectList;
39 d7f0c07d Leszek Koltunski
import org.distorted.overlays.DataStars;
40
import org.distorted.overlays.ListenerOverlay;
41
import org.distorted.overlays.OverlayStars;
42 1cd323dd Leszek Koltunski
import org.distorted.screens.RubikScreenPlay;
43 dd1a65c1 Leszek Koltunski
import org.distorted.screens.RubikScreenReady;
44
import org.distorted.screens.RubikScreenSolver;
45 1cd323dd Leszek Koltunski
import org.distorted.screens.RubikScreenSolving;
46
import org.distorted.screens.ScreenList;
47 dd1a65c1 Leszek Koltunski
import org.distorted.solvers.SolverMain;
48 1cd323dd Leszek Koltunski
49 e019c70b Leszek Koltunski
import java.lang.ref.WeakReference;
50
51 24679c47 Leszek Koltunski
import static org.distorted.external.RubikScores.RECORD_FIRST;
52 d7f0c07d Leszek Koltunski
import static org.distorted.external.RubikScores.RECORD_NEW;
53 24679c47 Leszek Koltunski
import static org.distorted.external.RubikScores.RECORD_NOT_NEW;
54
55 1cd323dd Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
56
57 d7f0c07d Leszek Koltunski
public class RubikObjectLibInterface implements ObjectLibInterface, ListenerOverlay
58 1cd323dd Leszek Koltunski
{
59 5c4ed8ed Leszek Koltunski
  private final WeakReference<RubikActivity> mAct;
60 24679c47 Leszek Koltunski
  private int mIsNewRecord;
61 1cd323dd Leszek Koltunski
  private long mNewRecord;
62 5c4ed8ed Leszek Koltunski
  private int mLastCubitColor, mLastCubit, mLastCubitFace;
63 1cd323dd Leszek Koltunski
64
///////////////////////////////////////////////////////////////////////////////////////////////////
65
66 e019c70b Leszek Koltunski
  RubikObjectLibInterface(RubikActivity act)
67
    {
68
    mAct = new WeakReference<>(act);
69 5c4ed8ed Leszek Koltunski
    mLastCubitColor = -1;
70 e019c70b Leszek Koltunski
    }
71
72
///////////////////////////////////////////////////////////////////////////////////////////////////
73
74
  private void analyticsReport(RubikActivity act, String message, String name, long timeBegin)
75 1cd323dd Leszek Koltunski
    {
76
    long elapsed = System.currentTimeMillis() - timeBegin;
77
    String msg = message+" startTime: "+timeBegin+" elapsed: "+elapsed+" name: "+name;
78
79
    if( BuildConfig.DEBUG )
80
       {
81 d38a302b Leszek Koltunski
       android.util.Log.d("libInterface", msg);
82 1cd323dd Leszek Koltunski
       }
83
    else
84
      {
85 e019c70b Leszek Koltunski
      FirebaseAnalytics analytics = act.getAnalytics();
86 1cd323dd Leszek Koltunski
87
      if( analytics!=null )
88
        {
89
        Bundle bundle = new Bundle();
90
        bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, msg);
91
        analytics.logEvent(FirebaseAnalytics.Event.SHARE, bundle);
92
        }
93
      }
94
    }
95
96
///////////////////////////////////////////////////////////////////////////////////////////////////
97
98 1fa125c2 Leszek Koltunski
  private void reportRecord(RubikActivity act, long startTime, long endTime, String debug, int scrambleNum)
99 1cd323dd Leszek Koltunski
    {
100 8ab435b9 Leszek Koltunski
    RubikScreenPlay play= (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
101
    RubikScores scores  = RubikScores.getInstance();
102 400ff34d Leszek Koltunski
    int object  = RubikObjectList.getCurrObject();
103 d433b50e Leszek Koltunski
    int level   = play.getLevel();
104
    String name = scores.getName();
105
    RubikObject obj = RubikObjectList.getObject(object);
106 84d746d7 Leszek Koltunski
    String objName = obj==null ? "NULL" : obj.getUpperName();
107 d433b50e Leszek Koltunski
108 d38a302b Leszek Koltunski
    String record = objName+" level "+level+" time "+mNewRecord+" isNew: "+mIsNewRecord+" scrambleNum: "+scrambleNum;
109 1cd323dd Leszek Koltunski
110
    if( BuildConfig.DEBUG )
111
       {
112 d38a302b Leszek Koltunski
       android.util.Log.e("libInterface", debug);
113
       android.util.Log.e("libInterface", name);
114
       android.util.Log.e("libInterface", record);
115 1cd323dd Leszek Koltunski
       }
116
    else
117
      {
118 1fa125c2 Leszek Koltunski
      if( level>=9 && mNewRecord<300*level )
119
        {
120 6eb4c104 Leszek Koltunski
        long timeNow = System.currentTimeMillis();
121
        long elapsed = timeNow - startTime;
122 1fa125c2 Leszek Koltunski
        String suspicious ="start"+startTime+"end"+endTime+"elapsed"+elapsed+"obj"+objName+"level"+level+"record"+mNewRecord+"scrambles"+scrambleNum+debug;
123
        RubikNetwork network = RubikNetwork.getInstance();
124 e4854e54 Leszek Koltunski
        network.suspicious(suspicious,act);
125 1fa125c2 Leszek Koltunski
        }
126
127 e019c70b Leszek Koltunski
      FirebaseAnalytics analytics = act.getAnalytics();
128 1cd323dd Leszek Koltunski
129
      if( analytics!=null )
130
        {
131
        Bundle bundle = new Bundle();
132
        bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, debug);
133
        bundle.putString(FirebaseAnalytics.Param.CHARACTER, name);
134
        bundle.putString(FirebaseAnalytics.Param.LEVEL, record);
135
        analytics.logEvent(FirebaseAnalytics.Event.LEVEL_UP, bundle);
136
        }
137
      }
138
    }
139
140
///////////////////////////////////////////////////////////////////////////////////////////////////
141
142 e019c70b Leszek Koltunski
  private void requestReview(RubikActivity act)
143 1cd323dd Leszek Koltunski
    {
144
    final RubikScores scores = RubikScores.getInstance();
145
    int numWins = scores.incrementNumWins();
146 53b4c7ad Leszek Koltunski
    int numRuns = scores.getNumRuns();
147 1cd323dd Leszek Koltunski
148 53b4c7ad Leszek Koltunski
    if( numRuns==3 || numRuns==6 || numWins==7 || numWins==30 || numWins==50 || numWins==80 || numWins==100)
149 1cd323dd Leszek Koltunski
      {
150
      final long timeBegin = System.currentTimeMillis();
151
      final ReviewManager manager = ReviewManagerFactory.create(act);
152
      Task<ReviewInfo> request = manager.requestReviewFlow();
153
154
      request.addOnCompleteListener(new OnCompleteListener<ReviewInfo>()
155
        {
156
        @Override
157
        public void onComplete (@NonNull Task<ReviewInfo> task)
158
          {
159
          if (task.isSuccessful())
160
            {
161
            final String name = scores.getName();
162
            ReviewInfo reviewInfo = task.getResult();
163
            Task<Void> flow = manager.launchReviewFlow(act, reviewInfo);
164
165
            flow.addOnFailureListener(new OnFailureListener()
166
              {
167
              @Override
168
              public void onFailure(Exception e)
169
                {
170
                analyticsReport(act,"Failed", name, timeBegin);
171
                }
172
              });
173
174
            flow.addOnCompleteListener(new OnCompleteListener<Void>()
175
              {
176
              @Override
177
              public void onComplete(@NonNull Task<Void> task)
178
                {
179
                analyticsReport(act,"Complete", name, timeBegin);
180
                }
181
              });
182
            }
183
          else
184
            {
185
            String name = scores.getName();
186
            analyticsReport(act,"Not Successful", name, timeBegin);
187
            }
188
          }
189
        });
190
      }
191
    }
192
193
///////////////////////////////////////////////////////////////////////////////////////////////////
194
195 e019c70b Leszek Koltunski
  public void onScrambleEffectFinished()
196
    {
197 dd874ae8 Leszek Koltunski
    RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
198 1cd323dd Leszek Koltunski
199 dd874ae8 Leszek Koltunski
    if( play.shouldReactToEndOfScrambling() )
200 e019c70b Leszek Koltunski
      {
201 dd874ae8 Leszek Koltunski
      RubikActivity act = mAct.get();
202
      RubikScores.getInstance().incrementNumPlays();
203
204
      act.runOnUiThread(new Runnable()
205
        {
206
        @Override
207
        public void run()
208 e019c70b Leszek Koltunski
        {
209
        ScreenList.switchScreen( act, ScreenList.READ);
210
        }
211 dd874ae8 Leszek Koltunski
        });
212
      }
213 e019c70b Leszek Koltunski
    }
214 1cd323dd Leszek Koltunski
215 e019c70b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
216
217
  public void onFinishRotation(int axis, int row, int angle)
218
    {
219
    if( ScreenList.getCurrentScreen()== ScreenList.SOLV )
220
      {
221
      RubikScreenSolving solv = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
222
      solv.addMove(mAct.get(), axis, row, angle);
223
      }
224
    if( ScreenList.getCurrentScreen()== ScreenList.PLAY )
225
      {
226
      RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
227
      play.addMove(mAct.get(), axis, row, angle);
228
      }
229
    }
230 1cd323dd Leszek Koltunski
231 dd1a65c1 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
232
233 e019c70b Leszek Koltunski
  public void onBeginRotation()
234
    {
235
    if( ScreenList.getCurrentScreen()== ScreenList.READ )
236
      {
237
      RubikScreenSolving solving = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
238
      solving.resetElapsed();
239
      RubikActivity act = mAct.get();
240
241
      act.runOnUiThread(new Runnable()
242
        {
243
        @Override
244
        public void run()
245
          {
246
          ScreenList.switchScreen( act, ScreenList.SOLV);
247
          }
248
        });
249
      }
250
    }
251 dd1a65c1 Leszek Koltunski
252
///////////////////////////////////////////////////////////////////////////////////////////////////
253
254 e019c70b Leszek Koltunski
  public void failedToDrag()
255
    {
256
    ScreenList curr = ScreenList.getCurrentScreen();
257
258
    if( curr==ScreenList.PLAY )
259
      {
260
      RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
261
      play.reddenLock(mAct.get());
262
      }
263
    else if( curr==ScreenList.READ )
264
      {
265
      RubikScreenReady read = (RubikScreenReady) ScreenList.READ.getScreenClass();
266
      read.reddenLock(mAct.get());
267
      }
268
    else if( curr==ScreenList.SOLV )
269
      {
270
      RubikScreenSolving solv = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
271
      solv.reddenLock(mAct.get());
272
      }
273
    }
274 dd1a65c1 Leszek Koltunski
275
///////////////////////////////////////////////////////////////////////////////////////////////////
276
277 e019c70b Leszek Koltunski
  public void onSolved()
278
    {
279
    if( ScreenList.getCurrentScreen()== ScreenList.SOLV )
280 dd1a65c1 Leszek Koltunski
      {
281 e019c70b Leszek Koltunski
      RubikScreenSolving solving = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
282 24679c47 Leszek Koltunski
      mNewRecord = solving.stopTimerAndGetRecord();
283
      mIsNewRecord = solving.setRecord();
284 dd1a65c1 Leszek Koltunski
      }
285 e019c70b Leszek Koltunski
    }
286 dd1a65c1 Leszek Koltunski
287 e709e44d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
288
289
  public void onObjectCreated(long time)
290
    {
291
292
    }
293
294 95472aca Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
295
296 eb647d5e Leszek Koltunski
  public void reportProblem(String problem, boolean recordException)
297 95472aca Leszek Koltunski
    {
298
    if( BuildConfig.DEBUG )
299
      {
300 d38a302b Leszek Koltunski
      android.util.Log.e("libInterface", problem);
301 95472aca Leszek Koltunski
      }
302
    else
303
      {
304 eb647d5e Leszek Koltunski
      if( recordException )
305
        {
306
        Exception ex = new Exception(problem);
307
        FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
308
        crashlytics.setCustomKey("problem" , problem);
309
        crashlytics.recordException(ex);
310
        }
311
      else
312
        {
313
        FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
314
        crashlytics.log(problem);
315
        }
316 95472aca Leszek Koltunski
      }
317
    }
318
319
///////////////////////////////////////////////////////////////////////////////////////////////////
320
321
  private void reportUIProblem(int place, long pause, long resume, long time)
322
    {
323
    String error = "UI BLOCK "+place+" blocked for "+time;
324
325
    if( BuildConfig.DEBUG )
326
       {
327 d38a302b Leszek Koltunski
       android.util.Log.e("libInterface", error);
328 95472aca Leszek Koltunski
       }
329
    else
330
      {
331
      Exception ex = new Exception(error);
332
      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
333
      crashlytics.setCustomKey("pause" , pause );
334
      crashlytics.setCustomKey("resume", resume );
335
      crashlytics.recordException(ex);
336
      }
337
    }
338
339
///////////////////////////////////////////////////////////////////////////////////////////////////
340
341
  private void reportTouchProblem(int place, long pause, long resume, long time)
342
    {
343
    String error = "TOUCH BLOCK "+place+" blocked for "+time;
344
345
    if( BuildConfig.DEBUG )
346
       {
347 d38a302b Leszek Koltunski
       android.util.Log.e("libInterface", error);
348 95472aca Leszek Koltunski
       }
349
    else
350
      {
351
      Exception ex = new Exception(error);
352
      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
353
      crashlytics.setCustomKey("pause" , pause );
354
      crashlytics.setCustomKey("resume", resume);
355
      crashlytics.recordException(ex);
356
      }
357
    }
358
359
///////////////////////////////////////////////////////////////////////////////////////////////////
360
361
  private void reportThreadProblem(int place, long pause, long resume, long time)
362
    {
363
    String error = EffectMessageSender.reportState();
364
365
    if( BuildConfig.DEBUG )
366
       {
367 d38a302b Leszek Koltunski
       android.util.Log.e("libInterface", error);
368 95472aca Leszek Koltunski
       }
369
    else
370
      {
371
      Exception ex = new Exception(error);
372
      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
373
      crashlytics.setCustomKey("pause" , pause  );
374
      crashlytics.setCustomKey("resume", resume );
375
      crashlytics.recordException(ex);
376
      }
377
    }
378
379
///////////////////////////////////////////////////////////////////////////////////////////////////
380
381
  public void reportBlockProblem(int type, int place, long pause, long resume, long time)
382
    {
383
    switch(type)
384
      {
385
      case BlockController.TYPE_UI    : reportUIProblem(place,pause,resume,time); break;
386
      case BlockController.TYPE_TOUCH : reportTouchProblem(place,pause,resume,time); break;
387
      case BlockController.TYPE_THREAD: reportThreadProblem(place,pause,resume,time); break;
388
      }
389
    }
390
391 c020555e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
392
393
  public void reportJSONError(String error, int ordinal)
394
    {
395
    RubikObject object = RubikObjectList.getObject(ordinal);
396
    String name = object==null ? "NULL" : object.getUpperName();
397
398
    if( BuildConfig.DEBUG )
399
       {
400
       android.util.Log.e("libInterface", "name="+name+" JSON error: "+error);
401
       }
402
    else
403
      {
404
      Exception ex = new Exception(error);
405
      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
406
      crashlytics.setCustomKey("name" , name );
407
      crashlytics.setCustomKey("JSONerror", error );
408
      crashlytics.recordException(ex);
409
      }
410
    }
411
412 1cd323dd Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
413
414 5c4ed8ed Leszek Koltunski
  public void onReplaceModeDown(int cubit, int face)
415 e019c70b Leszek Koltunski
    {
416
    RubikScreenSolver solver = (RubikScreenSolver) ScreenList.SVER.getScreenClass();
417 5c4ed8ed Leszek Koltunski
    int color = solver.getCurrentColor();
418 400ff34d Leszek Koltunski
    int currObject = RubikObjectList.getCurrObject();
419 5c4ed8ed Leszek Koltunski
    mLastCubitColor = SolverMain.cubitIsLocked(currObject,cubit);
420
    mLastCubit = cubit;
421
    mLastCubitFace = face;
422
    ObjectControl control = mAct.get().getControl();
423
    control.setTextureMap( cubit, face, color );
424 e019c70b Leszek Koltunski
    }
425 1cd323dd Leszek Koltunski
426 e019c70b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
427
428 5c4ed8ed Leszek Koltunski
  public void onReplaceModeUp()
429 e019c70b Leszek Koltunski
    {
430 5c4ed8ed Leszek Koltunski
    if( mLastCubitColor>=0 )
431
      {
432
      ObjectControl control = mAct.get().getControl();
433
      control.setTextureMap( mLastCubit, mLastCubitFace, mLastCubitColor );
434
      mLastCubitColor = -1;
435
      }
436 e019c70b Leszek Koltunski
    }
437 d7f0c07d Leszek Koltunski
438
///////////////////////////////////////////////////////////////////////////////////////////////////
439
440
  public void onWinEffectFinished(long startTime, long endTime, String debug, int scrambleNum)
441
    {
442
    if( ScreenList.getCurrentScreen()== ScreenList.SOLV )
443
      {
444
      RubikActivity act = mAct.get();
445
      Bundle bundle = new Bundle();
446
      bundle.putLong("time", mNewRecord );
447
448
      reportRecord(act,startTime,endTime,debug,scrambleNum);
449
      requestReview(act);
450
451
      switch(mIsNewRecord)
452
        {
453 240bf467 Leszek Koltunski
        case RECORD_FIRST  : /*
454
                             // temporarily switch off the 'stars' animation
455
                             RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
456 d7f0c07d Leszek Koltunski
                             int level = play.getLevel();
457
                             RubikScores scores = RubikScores.getInstance();
458
                             int totStars = scores.getNumStars();
459
                             int newStars = RubikObjectList.computeNumStars(level);
460
                             DistortedScreen screen = act.getScreen();
461
462
                             OverlayStars stars = new OverlayStars();
463
                             DataStars data  = new DataStars(totStars,newStars,act.getResources());
464
                             stars.startOverlay(screen,this,data);
465
                             break;
466 240bf467 Leszek Koltunski
                             */
467 d7f0c07d Leszek Koltunski
        case RECORD_NEW    : RubikDialogNewRecord d2 = new RubikDialogNewRecord();
468
                             d2.setArguments(bundle);
469
                             d2.show( act.getSupportFragmentManager(), RubikDialogNewRecord.getDialogTag() );
470
                             break;
471
        case RECORD_NOT_NEW: RubikDialogSolved d3 = new RubikDialogSolved();
472
                             d3.setArguments(bundle);
473
                             d3.show( act.getSupportFragmentManager(), RubikDialogSolved.getDialogTag() );
474
                             break;
475
        }
476
477
      act.runOnUiThread(new Runnable()
478
        {
479
        @Override
480
        public void run()
481
          {
482
          ScreenList.switchScreen( act, ScreenList.DONE);
483
          }
484
        });
485
      }
486
    }
487
488
///////////////////////////////////////////////////////////////////////////////////////////////////
489
490
  public void overlayFinished(long id)
491
    {
492
    RubikActivity act = mAct.get();
493
    Bundle bundle = new Bundle();
494
    bundle.putLong("time", mNewRecord );
495
496
    RubikDialogNewRecord d2 = new RubikDialogNewRecord();
497
    d2.setArguments(bundle);
498
    d2.show( act.getSupportFragmentManager(), RubikDialogNewRecord.getDialogTag() );
499
    }
500 1cd323dd Leszek Koltunski
}