From a57aac8f809e37cfa8e98b52b040ebccb803d5ab Mon Sep 17 00:00:00 2001 From: JFronny Date: Wed, 13 Jul 2022 15:49:04 +0200 Subject: [PATCH 1/3] Clean up various things --- app/build.gradle | 41 +- .../ExampleInstrumentedTest.java | 4 +- app/src/main/AndroidManifest.xml | 3 +- .../activity/AboutActivity.java | 14 +- .../activity/BaseActivity.java | 45 +- .../activity/GameActivity.java | 589 ++++-------------- .../activity/HelpActivity.java | 6 +- .../activity/MainActivity.java | 26 +- .../activity/SettingsActivity.java | 93 ++- .../activity/SplashActivity.java | 2 +- .../activity/StartClientActivity.java | 74 +-- .../activity/StartHostActivity.java | 36 +- .../activity/TutorialActivity.java | 70 +-- .../adapter/PlayerAdapter.java | 12 +- .../client/ClientGameController.java | 210 +++---- .../client/WebsocketClientHandler.java | 4 +- .../context/GameContext.java | 2 +- .../dialog/GameInformationDialog.java | 23 +- .../dialog/PlayerInputDialog.java | 46 +- .../dialog/TextDialog.java | 14 +- .../dialog/VotingDialog.java | 29 +- .../dialog/WitchDialog.java | 28 +- .../helpers/ExpandableListAdapter.java | 14 +- .../helpers/HelpDataDump.java | 4 +- .../helpers/PermissionHelper.java | 12 +- .../helpers/PlayerCardClickListener.java | 8 +- .../model/NetworkPackage.java | 3 - .../privacyfriendlywerwolf/model/Player.java | 10 +- .../preferences/NumberPickerPreference.java | 1 - .../server/ServerGameController.java | 12 +- .../server/WebSocketServerHandler.java | 235 ++++--- .../util/ContextUtil.java | 4 - .../privacyfriendlywerwolf/util/Screen.java | 25 +- app/src/main/res/layout/activity_game.xml | 10 +- app/src/main/res/layout/activity_help.xml | 16 +- app/src/main/res/layout/activity_main.xml | 10 +- app/src/main/res/layout/activity_settings.xml | 10 +- .../main/res/layout/activity_start_client.xml | 10 +- .../main/res/layout/activity_start_host.xml | 10 +- app/src/main/res/layout/activity_tutorial.xml | 2 +- app/src/main/res/layout/toolbar.xml | 6 +- app/src/main/res/values-de/strings.xml | 20 +- app/src/main/res/values/strings.xml | 18 +- build.gradle | 2 +- gradle.properties | 2 + gradle/wrapper/gradle-wrapper.properties | 7 +- 46 files changed, 638 insertions(+), 1184 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index acfe586..6e2a87d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,16 +1,16 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 25 + compileSdkVersion 32 defaultConfig { vectorDrawables.useSupportLibrary = true applicationId 'org.secuso.privacyfriendlycardgameone' minSdkVersion 21 - targetSdkVersion 25 + targetSdkVersion 32 versionCode 2 versionName "1.0.1" - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' } buildTypes { release { @@ -18,42 +18,33 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } - lintOptions { - abortOnError false - } - packagingOptions { - exclude 'META-INF/DEPENDENCIES.txt' - exclude 'META-INF/LICENSE.txt' - exclude 'META-INF/NOTICE.txt' - exclude 'META-INF/NOTICE' - exclude 'META-INF/LICENSE' - exclude 'META-INF/DEPENDENCIES' - exclude 'META-INF/notice.txt' - exclude 'META-INF/license.txt' - exclude 'META-INF/dependencies.txt' - pickFirst 'META-INF/services/javax.ws.rs.ext.MessageBodyReader' - pickFirst 'META-INF/services/javax.ws.rs.ext.MessageBodyWriter' - pickFirst 'META-INF/jersey-module-version' - pickFirst 'META-INF/services/com.sun.jersey.spi.inject.InjectableProvider' + resources { + excludes += ['META-INF/DEPENDENCIES.txt', 'META-INF/LICENSE.txt', 'META-INF/NOTICE.txt', 'META-INF/NOTICE', 'META-INF/LICENSE', 'META-INF/DEPENDENCIES', 'META-INF/notice.txt', 'META-INF/license.txt', 'META-INF/dependencies.txt'] + pickFirsts += ['META-INF/services/javax.ws.rs.ext.MessageBodyReader', 'META-INF/services/javax.ws.rs.ext.MessageBodyWriter', 'META-INF/jersey-module-version', 'META-INF/services/com.sun.jersey.spi.inject.InjectableProvider'] + } } + productFlavors { } + lint { + abortOnError false + } } dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') - androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', { + androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', { exclude group: 'com.android.support', module: 'support-annotations' }) - implementation 'com.android.support:appcompat-v7:25.4.0' + implementation 'androidx.appcompat:appcompat:1.4.2' testImplementation 'junit:junit:4.12' - implementation 'com.android.support:design:25.4.0' - implementation 'com.android.support:support-v4:25.4.0' + implementation 'com.google.android.material:material:1.6.1' + implementation 'androidx.legacy:legacy-support-v4:1.0.0' // compile 'com.journeyapps:zxing-android-embedded:3.4.0' // compile 'com.github.kenglxn.QRGen:android:2.2.0' implementation 'com.koushikdutta.async:androidasync:2.2.1' - implementation 'com.google.code.gson:gson:2.8.2' + implementation 'com.google.code.gson:gson:2.9.0' testImplementation 'junit:junit:4.12' testImplementation 'org.powermock:powermock:1.6.5' testImplementation 'org.powermock:powermock-module-junit4:1.6.5' diff --git a/app/src/androidTest/java/org/secuso/privacyfriendlywerwolf/ExampleInstrumentedTest.java b/app/src/androidTest/java/org/secuso/privacyfriendlywerwolf/ExampleInstrumentedTest.java index 2f0a347..12ce313 100644 --- a/app/src/androidTest/java/org/secuso/privacyfriendlywerwolf/ExampleInstrumentedTest.java +++ b/app/src/androidTest/java/org/secuso/privacyfriendlywerwolf/ExampleInstrumentedTest.java @@ -1,8 +1,8 @@ package org.secuso.privacyfriendlywerwolf; import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3e6f5c5..86236f9 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -59,7 +59,8 @@ + android:theme="@style/SplashTheme" + android:exported="true"> diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/AboutActivity.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/AboutActivity.java index 71f860e..d11824c 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/AboutActivity.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/AboutActivity.java @@ -1,8 +1,8 @@ package org.secuso.privacyfriendlywerwolf.activity; import android.os.Bundle; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AppCompatActivity; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; import android.text.method.LinkMovementMethod; import android.view.View; import android.widget.TextView; @@ -36,11 +36,11 @@ protected void onCreate(Bundle savedInstanceState) { overridePendingTransition(0, 0); // Open links to websites - ((TextView)findViewById(R.id.secusoWebsite)).setMovementMethod(LinkMovementMethod.getInstance()); - ((TextView)findViewById(R.id.githubURL)).setMovementMethod(LinkMovementMethod.getInstance()); - ((TextView)findViewById(R.id.license_cc_url)).setMovementMethod(LinkMovementMethod.getInstance()); - ((TextView)findViewById(R.id.credit_url)).setMovementMethod(LinkMovementMethod.getInstance()); - ((TextView)findViewById(R.id.textFieldVersionName)).setText(BuildConfig.VERSION_NAME); + this.findViewById(R.id.secusoWebsite).setMovementMethod(LinkMovementMethod.getInstance()); + this.findViewById(R.id.githubURL).setMovementMethod(LinkMovementMethod.getInstance()); + this.findViewById(R.id.license_cc_url).setMovementMethod(LinkMovementMethod.getInstance()); + this.findViewById(R.id.credit_url).setMovementMethod(LinkMovementMethod.getInstance()); + this.findViewById(R.id.textFieldVersionName).setText(BuildConfig.VERSION_NAME); } diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/BaseActivity.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/BaseActivity.java index 9a0251f..09253e8 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/BaseActivity.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/BaseActivity.java @@ -2,19 +2,18 @@ import android.content.Intent; import android.content.SharedPreferences; -import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.preference.PreferenceActivity; import android.preference.PreferenceManager; -import android.support.design.widget.NavigationView; -import android.support.design.widget.NavigationView.OnNavigationItemSelectedListener; -import android.support.v4.app.TaskStackBuilder; -import android.support.v4.view.GravityCompat; -import android.support.v4.widget.DrawerLayout; -import android.support.v7.app.ActionBarDrawerToggle; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; +import com.google.android.material.navigation.NavigationView; +import com.google.android.material.navigation.NavigationView.OnNavigationItemSelectedListener; +import androidx.core.app.TaskStackBuilder; +import androidx.core.view.GravityCompat; +import androidx.drawerlayout.widget.DrawerLayout; +import androidx.appcompat.app.ActionBarDrawerToggle; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; import android.view.MenuItem; import android.view.View; @@ -60,7 +59,7 @@ protected void onCreate(Bundle savedInstanceState) { @Override public void onBackPressed() { - DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); + DrawerLayout drawer = findViewById(R.id.drawer_layout); if (drawer.isDrawerOpen(GravityCompat.START)) { drawer.closeDrawer(GravityCompat.START); } else { @@ -88,12 +87,7 @@ protected boolean goToNavigationItem(final int itemId) { } // delay transition so the drawer can close - mHandler.postDelayed(new Runnable() { - @Override - public void run() { - callDrawerItem(itemId); - } - }, NAVDRAWER_LAUNCH_DELAY); + mHandler.postDelayed(() -> callDrawerItem(itemId), NAVDRAWER_LAUNCH_DELAY); mDrawerLayout.closeDrawer(GravityCompat.START); @@ -122,14 +116,9 @@ private void selectNavigationItem(int itemId) { * @param intent */ private void createBackStack(Intent intent) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - TaskStackBuilder builder = TaskStackBuilder.create(this); - builder.addNextIntentWithParentStack(intent); - builder.startActivities(); - } else { - startActivity(intent); - finish(); - } + TaskStackBuilder builder = TaskStackBuilder.create(this); + builder.addNextIntentWithParentStack(intent); + builder.startActivities(); } /** @@ -150,7 +139,7 @@ private void callDrawerItem(final int itemId) { case R.id.nav_new_game: PlayerInputDialog playerInputDialog = new PlayerInputDialog(); playerInputDialog.setCancelable(false); - playerInputDialog.show(getFragmentManager(), "dialog_from_drawer"); + playerInputDialog.show(getSupportFragmentManager(), "dialog_from_drawer"); break; case R.id.nav_join_game: intent = new Intent(this, StartClientActivity.class); @@ -183,19 +172,19 @@ private void callDrawerItem(final int itemId) { protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); - Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + Toolbar toolbar = findViewById(R.id.toolbar); if (getSupportActionBar() == null) { setSupportActionBar(toolbar); } if (!this.getClass().equals(GameActivity.class)) { - mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); + mDrawerLayout = findViewById(R.id.drawer_layout); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( this, mDrawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); mDrawerLayout.addDrawerListener(toggle); toggle.syncState(); - mNavigationView = (NavigationView) findViewById(R.id.nav_view); + mNavigationView = findViewById(R.id.nav_view); mNavigationView.setNavigationItemSelectedListener(this); selectNavigationItem(getNavigationDrawerID()); diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/GameActivity.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/GameActivity.java index fa40a9f..036a425 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/GameActivity.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/GameActivity.java @@ -1,7 +1,6 @@ package org.secuso.privacyfriendlywerwolf.activity; import android.animation.ObjectAnimator; -import android.content.DialogInterface; import android.content.Intent; import android.content.res.ColorStateList; import android.media.MediaPlayer; @@ -10,10 +9,10 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; -import android.support.design.widget.FloatingActionButton; -import android.support.v4.content.ContextCompat; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AlertDialog; +import com.google.android.material.floatingactionbutton.FloatingActionButton; +import androidx.core.content.ContextCompat; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AlertDialog; import android.util.Log; import android.view.Menu; import android.view.MenuItem; @@ -114,63 +113,43 @@ protected void onCreate(Bundle savedInstanceState) { outputMessage(R.string.progressBar_initial); longOutputMessage(R.string.gameStart_hintRoles); - fab = (FloatingActionButton) findViewById(R.id.next_fab); + fab = findViewById(R.id.next_fab); fab.setVisibility(View.VISIBLE); // if all players are connected the host can start the game // by clicking the start_game_button - fab.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - gameHandler.post(new Runnable() { - @Override - public void run() { - ServerGameController.HOST_IS_DONE = true; - ServerGameController.CLIENTS_ARE_DONE = true; - if (ContextUtil.IS_FIRST_ROUND) { - Log.d(TAG, "FabButton clicked on Phase: " + gameController.getGameContext().getCurrentPhase().toString()); - - // at the end of the first round - if (ContextUtil.END_OF_ROUND && gameController.getGameContext().getCurrentPhase() != null - && (gameController.getGameContext().getCurrentPhase() == GamePhaseEnum.GAME_START)) { - // first round is over - ContextUtil.IS_FIRST_ROUND = false; - } - runOnUiThread(new Runnable() { - @Override - public void run() { - // disable info text - TextView view = (TextView) findViewById(R.id.fab_info_view); - view.setVisibility(View.GONE); - } - }); - - } - deactivateNextButton(); - ServerGameController.getInstance().startNextPhase(); - } + fab.setOnClickListener(v -> gameHandler.post(() -> { + ServerGameController.HOST_IS_DONE = true; + ServerGameController.CLIENTS_ARE_DONE = true; + if (ContextUtil.IS_FIRST_ROUND) { + Log.d(TAG, "FabButton clicked on Phase: " + gameController.getGameContext().getCurrentPhase().toString()); + + // at the end of the first round + if (ContextUtil.END_OF_ROUND && gameController.getGameContext().getCurrentPhase() != null + && (gameController.getGameContext().getCurrentPhase() == GamePhaseEnum.GAME_START)) { + // first round is over + ContextUtil.IS_FIRST_ROUND = false; + } + runOnUiThread(() -> { + // disable info text + TextView view = findViewById(R.id.fab_info_view); + view.setVisibility(View.GONE); }); + } - }); + deactivateNextButton(); + ServerGameController.getInstance().startNextPhase(); + })); if (Constants.GAME_FEATURES_ACTIVATED) { fab.setClickable(false); } - gameHandler.postDelayed(new Runnable() { - @Override - public void run() { - activateNextButton(); - showTextPopup("Ready, Set, Go!", R.string.popup_text_start_first_night); - runOnUiThread(new Runnable() { - @Override - public void run() { - TextView view = (TextView) findViewById(R.id.fab_info_view); - view.setVisibility(View.VISIBLE); - } - }); - } + gameHandler.postDelayed(() -> { + activateNextButton(); + showTextPopup("Ready, Set, Go!", R.string.popup_text_start_first_night); + runOnUiThread(() -> this.findViewById(R.id.fab_info_view).setVisibility(View.VISIBLE)); }, 6000); serverGameController = ServerGameController.getInstance(); @@ -202,13 +181,10 @@ public boolean onCreateOptionsMenu(Menu menu) { * open the voting dialog */ public void openVoting() { - runOnUiThread(new Runnable() { - @Override - public void run() { - VotingDialog votingDialog = new VotingDialog(); - votingDialog.setCancelable(false); - votingDialog.show(getFragmentManager(), "voting"); - } + runOnUiThread(() -> { + VotingDialog votingDialog = new VotingDialog(); + votingDialog.setCancelable(false); + votingDialog.show(getSupportFragmentManager(), "voting"); }); } @@ -220,17 +196,13 @@ public void run() { * @param message, the message of the dialog */ public void showTextPopup(final String title, final String message) { - runOnUiThread(new Runnable() { - @Override - public void run() { - TextDialog textDialog = new TextDialog(); - textDialog.setDialogText(message); - textDialog.setDialogTitle(title); - textDialog.setCancelable(false); - textDialog.show(getFragmentManager(), "textPopup"); - } + runOnUiThread(() -> { + TextDialog textDialog = new TextDialog(); + textDialog.setDialogText(message); + textDialog.setDialogTitle(title); + textDialog.setCancelable(false); + textDialog.show(getSupportFragmentManager(), "textPopup"); }); - } /** @@ -240,18 +212,7 @@ public void run() { * @param message, the message of the dialog */ public void showTextPopup(int titleInt, final String message) { - final String title = getResources().getString(titleInt); - runOnUiThread(new Runnable() { - @Override - public void run() { - TextDialog textDialog = new TextDialog(); - textDialog.setDialogText(message); - textDialog.setDialogTitle(title); - textDialog.setCancelable(false); - textDialog.show(getFragmentManager(), "textPopup"); - } - }); - + showTextPopup(getResources().getString(titleInt), message); } /** @@ -260,41 +221,8 @@ public void run() { * @param title, the title of the dialog * @param messageInt, the message of the dialog, coded in string.xml */ - public void showTextPopup(final String title, int messageInt) { - final String message = getResources().getString(messageInt); - runOnUiThread(new Runnable() { - @Override - public void run() { - TextDialog textDialog = new TextDialog(); - textDialog.setDialogText(message); - textDialog.setDialogTitle(title); - textDialog.setCancelable(false); - textDialog.show(getFragmentManager(), "textPopup"); - } - }); - - } - - /** - * shows a text popup with a title and a message - * - * @param titleInt, the title of the dialog - * @param messageInt, the message of the dialog - */ - public void showTextPopup(int titleInt, int messageInt) { - final String title = getResources().getString(titleInt); - final String message = getResources().getString(messageInt); - runOnUiThread(new Runnable() { - @Override - public void run() { - TextDialog textDialog = new TextDialog(); - textDialog.setDialogText(message); - textDialog.setDialogTitle(title); - textDialog.setCancelable(false); - textDialog.show(getFragmentManager(), "textPopup"); - } - }); - + public void showTextPopup(final String title, int messageInt, Object... messageArgs) { + showTextPopup(title, getResources().getString(messageInt, messageArgs)); } /** @@ -303,43 +231,8 @@ public void run() { * @param titleInt, the title of the dialog * @param messageInt, the message of the dialog */ - public void showTextPopup(int titleInt, int messageInt, final String extra) { - final String title = getResources().getString(titleInt); - final String message = getResources().getString(messageInt); - runOnUiThread(new Runnable() { - @Override - public void run() { - TextDialog textDialog = new TextDialog(); - textDialog.setDialogTitle(title); - textDialog.setDialogText(message + " " + extra); - textDialog.setCancelable(false); - textDialog.show(getFragmentManager(), "textPopup"); - } - }); - - } - - /** - * shows a text popup with a title and a message - * - * @param titleInt, the title of the dialog - * @param message, the message of the dialog - * @paraam extraInt, extra to the message, coded in string.xml - */ - public void showTextPopup(int titleInt, final String message, int extraInt) { - final String title = getResources().getString(titleInt); - final String extra = getResources().getString(extraInt); - runOnUiThread(new Runnable() { - @Override - public void run() { - TextDialog textDialog = new TextDialog(); - textDialog.setDialogTitle(title); - textDialog.setDialogText(message + " " + extra); - textDialog.setCancelable(false); - textDialog.show(getFragmentManager(), "textPopup"); - } - }); - + public void showTextPopup(int titleInt, int messageInt, Object... messageArgs) { + showTextPopup(getResources().getString(titleInt), getResources().getString(messageInt, messageArgs)); } /** @@ -349,51 +242,11 @@ public void run() { */ public void showGameEndTextView(int titleInt) { final String title = getResources().getString(titleInt); - runOnUiThread(new Runnable() { - @Override - public void run() { - TextView view = (TextView) findViewById(R.id.game_end_view); - view.setText(title); - view.setVisibility(View.VISIBLE); - } - }); - } - - /** - * shows the endGame dialog - * - * @param title, the title of the dialog - */ - public void showGameEndTextView(final String title) { - runOnUiThread(new Runnable() { - @Override - public void run() { - TextView view = (TextView) findViewById(R.id.game_end_view); - view.setText(title); - view.setVisibility(View.VISIBLE); - } - }); - } - - /** - * shows the witch dialog - * - * @param title, the title of the dialog - * @param message, the message of the dialog - */ - public void showWitchTextPopup(final String title, final String message) { - runOnUiThread(new Runnable() { - @Override - public void run() { - TextDialog textDialog = new TextDialog(); - textDialog.setDialogText(message); - textDialog.setDialogTitle(title); - textDialog.setMargin(0.15F); - textDialog.setCancelable(false); - textDialog.show(getFragmentManager(), "textPopup"); - } + runOnUiThread(() -> { + TextView view = findViewById(R.id.game_end_view); + view.setText(title); + view.setVisibility(View.VISIBLE); }); - } /** @@ -404,149 +257,50 @@ public void run() { */ public void showWitchTextPopup(int titleInt, final String message) { final String title = getResources().getString(titleInt); - runOnUiThread(new Runnable() { - @Override - public void run() { - TextDialog textDialog = new TextDialog(); - textDialog.setDialogText(message); - textDialog.setDialogTitle(title); - textDialog.setMargin(0.15F); - textDialog.setCancelable(false); - textDialog.show(getFragmentManager(), "textPopup"); - } - }); - - } - - /** - * shows the witch dialog - * - * @param titleInt, the title of the dialog - * @param messageInt, the message of the dialog - */ - public void showWitchElixirPopup(int titleInt, int messageInt) { - final String title = getResources().getString(titleInt); - final String message = getResources().getString(messageInt); - runOnUiThread(new Runnable() { - @Override - public void run() { - WitchDialog textDialog = WitchDialog.newInstance(0); - textDialog.setDialogText(message); - textDialog.setDialogTitle(title); - textDialog.setCancelable(false); - textDialog.show(getFragmentManager(), "textPopup"); - } + runOnUiThread(() -> { + TextDialog textDialog = new TextDialog(); + textDialog.setDialogText(message); + textDialog.setDialogTitle(title); + textDialog.setMargin(0.15F); + textDialog.setCancelable(false); + textDialog.show(getSupportFragmentManager(), "textPopup"); }); } /** * shows the witch dialog - * - * @param titleInt, the title of the dialog - * @param message, the message of the dialog */ - public void showWitchElixirPopup(int titleInt, final String message) { - final String title = getResources().getString(titleInt); - runOnUiThread(new Runnable() { - @Override - public void run() { - WitchDialog textDialog = WitchDialog.newInstance(0); - textDialog.setDialogText(message); - textDialog.setDialogTitle(title); - textDialog.setCancelable(false); - textDialog.show(getFragmentManager(), "textPopup"); - } - }); - } - - /** - * shows the witch elixir dialog - * - * @param title, the title of the dialog - * @param message, the message of the dialog - */ - public void showWitchElixirPopup(final String title, final String message) { - runOnUiThread(new Runnable() { - @Override - public void run() { - WitchDialog textDialog = WitchDialog.newInstance(0); - textDialog.setDialogText(message); - textDialog.setDialogTitle(title); - textDialog.setCancelable(false); - textDialog.show(getFragmentManager(), "textPopup"); - } - }); - } - - /** - * shows the witch poison dialog - * - * @param titleInt, the title of the dialog - * @param messageInt, the message of the dialog - */ - public void showWitchPoisonPopup(int titleInt, int messageInt) { - final String title = getResources().getString(titleInt); - final String message = getResources().getString(messageInt); - runOnUiThread(new Runnable() { - @Override - public void run() { - WitchDialog textDialog = WitchDialog.newInstance(1); - textDialog.setDialogText(message); - textDialog.setDialogTitle(title); - textDialog.setCancelable(false); - textDialog.show(getFragmentManager(), "textPopup"); - } - }); - } - - /** - * shows the witch poison dialog - * - * @param titleInt, the title of the dialog - * @param message, the message of the dialog - */ - public void showWitchPoisonPopup(int titleInt, final String message) { - final String title = getResources().getString(titleInt); - runOnUiThread(new Runnable() { - @Override - public void run() { - WitchDialog textDialog = WitchDialog.newInstance(1); - textDialog.setDialogText(message); - textDialog.setDialogTitle(title); - textDialog.setCancelable(false); - textDialog.show(getFragmentManager(), "textPopup"); - } + public void showWitchElixirPopup() { + final String title = getResources().getString(R.string.gamefield_witch_elixir_action); + final String message = getResources().getString(R.string.gamefield_witch_elixir_action_message2); + runOnUiThread(() -> { + WitchDialog textDialog = WitchDialog.newInstance(0); + textDialog.setDialogText(message); + textDialog.setDialogTitle(title); + textDialog.setCancelable(false); + textDialog.show(getSupportFragmentManager(), "textPopup"); }); } /** * shows the witch poison dialog - * - * @param title, the title of the dialog - * @param message, the message of the dialog */ - public void showWitchPoisonPopup(final String title, final String message) { - runOnUiThread(new Runnable() { - @Override - public void run() { - WitchDialog textDialog = WitchDialog.newInstance(1); - textDialog.setDialogText(message); - textDialog.setDialogTitle(title); - textDialog.setCancelable(false); - textDialog.show(getFragmentManager(), "textPopup"); - } + public void showWitchPoisonPopup() { + final String title = getResources().getString(R.string.gamefield_witch_poison_action); + final String message = getResources().getString(R.string.gamefield_witch_poison_action_message); + runOnUiThread(() -> { + WitchDialog textDialog = WitchDialog.newInstance(1); + textDialog.setDialogText(message); + textDialog.setDialogTitle(title); + textDialog.setCancelable(false); + textDialog.show(getSupportFragmentManager(), "textPopup"); }); } public void doPositiveClick(int i) { if (i == ELIXIR_CLICK) { ClientGameController.getInstance().usedElixir(); - gameHandler.post(new Runnable() { - @Override - public void run() { - gameController.endWitchElixirPhase(); - } - }); + gameHandler.post(() -> gameController.endWitchElixirPhase()); } else if (i == POISON_CLICK) { outputMessage(R.string.progressBar_choose); @@ -557,22 +311,13 @@ public void run() { public void doNegativeClick(int i) { if (i == ELIXIR_CLICK) { - gameHandler.post(new Runnable() { - @Override - public void run() { - gameController.endWitchElixirPhase(); - } - }); - + gameHandler.post(() -> gameController.endWitchElixirPhase()); //ClientGameController.getInstance().usePoison(); } else if (i == POISON_CLICK) { - gameHandler.postDelayed(new Runnable() { - @Override - public void run() { - longOutputMessage(R.string.toast_close_eyes); + gameHandler.postDelayed(() -> { + longOutputMessage(R.string.toast_close_eyes); - gameController.endWitchPoisonPhase(); - } + gameController.endWitchPoisonPhase(); }, 1000); //ClientGameController.getInstance().endWitchPhase(); @@ -581,33 +326,16 @@ public void run() { } } - public void askWitchForElixir() { - showWitchElixirPopup(R.string.gamefield_witch_elixir_action, getString(R.string.gamefield_witch_elixir_action_message2)); - } - - - public void askWitchForPoison() { - showWitchPoisonPopup(R.string.gamefield_witch_poison_action, R.string.gamefield_witch_poison_action_message); - } - - public void showYesNoBox(final int icon, final int title, final int message, final DialogInterface.OnClickListener yesAction, final DialogInterface.OnClickListener noAction) { - - - } - /** * shows little hint when and for what to press the next button * * @param info text to be displayed to the host */ public void showFabInfo(final String info) { - runOnUiThread(new Runnable() { - @Override - public void run() { - TextView view = (TextView) findViewById(R.id.fab_info_view); - view.setText(info); - view.setVisibility(View.VISIBLE); - } + runOnUiThread(() -> { + TextView view = findViewById(R.id.fab_info_view); + view.setText(info); + view.setVisibility(View.VISIBLE); }); } @@ -618,97 +346,53 @@ public void run() { */ public void showFabInfo(int infoInt) { final String info = getResources().getString(infoInt); - runOnUiThread(new Runnable() { - @Override - public void run() { - TextView view = (TextView) findViewById(R.id.fab_info_view); - view.setText(info); - view.setVisibility(View.VISIBLE); - } + runOnUiThread(() -> { + TextView view = findViewById(R.id.fab_info_view); + view.setText(info); + view.setVisibility(View.VISIBLE); }); } // make the NextButton clickable public void activateNextButton() { - runOnUiThread(new Runnable() { - @Override - public void run() { - fab.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(getApplicationContext(), R.color.colorAccent))); - fab.setClickable(true); - } - } - - ); + runOnUiThread(() -> { + fab.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(getApplicationContext(), R.color.colorAccent))); + fab.setClickable(true); + }); } // make the NextButton unclickable public void deactivateNextButton() { - runOnUiThread(new Runnable() { - @Override - public void run() { - fab.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(getApplicationContext(), R.color.middlegrey))); - if (Constants.GAME_FEATURES_ACTIVATED) { - fab.setClickable(false); - } - } - } - - ); + runOnUiThread(() -> { + fab.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(getApplicationContext(), R.color.middlegrey))); + if (Constants.GAME_FEATURES_ACTIVATED) { + fab.setClickable(false); + } + }); } public void outputMessage(final String message) { - runOnUiThread(new Runnable() { - - @Override - public void run() { - messageView.setText(message); - } - }); + runOnUiThread(() -> messageView.setText(message)); } public void outputMessage(int messageInt) { final String message = this.getResources().getString(messageInt); - runOnUiThread(new Runnable() { - - @Override - public void run() { - messageView.setText(message); - } - }); - + runOnUiThread(() -> messageView.setText(message)); } public void longOutputMessage(final String message) { // accessing UI thread from background thread - runOnUiThread(new Runnable() { - - @Override - public void run() { - Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show(); - } - }); + runOnUiThread(() -> Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show()); } public void longOutputMessage(int messageInt) { final String message = getResources().getString(messageInt); - runOnUiThread(new Runnable() { - - @Override - public void run() { - Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show(); - } - }); + runOnUiThread(() -> Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show()); } public void longOutputMessage(int messageInt, final String extra) { final String message = getResources().getString(messageInt); - runOnUiThread(new Runnable() { - - @Override - public void run() { - Toast.makeText(getApplicationContext(), message + " " + extra, Toast.LENGTH_LONG).show(); - } - }); + runOnUiThread(() -> Toast.makeText(getApplicationContext(), message + " " + extra, Toast.LENGTH_LONG).show()); } /** @@ -724,12 +408,12 @@ public CountDownTimer makeTimer(int seconds) { } // get objects from view - final ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar); - final TextView countdown = (TextView) findViewById(R.id.countdown); + final ProgressBar progressBar = findViewById(R.id.progressBar); + final TextView countdown = findViewById(R.id.countdown); progressBar.setMax(seconds * 1000); - this.countDownTimer = new CountDownTimer(seconds * 1000, 1000) { + this.countDownTimer = new CountDownTimer(seconds * 1000L, 1000) { ClientGameController gameController = ClientGameController.getInstance(); @@ -748,7 +432,7 @@ public void onTick(long millisUntilFinished) { animation.start(); // progressBar.setProgress(Long.valueOf(progress).intValue()); - countdown.setText(Long.valueOf(progress / 1000).toString() + " s"); + countdown.setText((progress / 1000L) + " s"); } /** @@ -769,13 +453,10 @@ public void onFinish() { */ public void updateGamefield() { final GameActivity gameActivity = this; - runOnUiThread(new Runnable() { - @Override - public void run() { - GridView layout = (GridView) findViewById(R.id.players); - playerAdapter = new PlayerAdapter(gameActivity, gameController.getMyPlayerId()); - layout.setAdapter(playerAdapter); - } + runOnUiThread(() -> { + GridView layout = findViewById(R.id.players); + playerAdapter = new PlayerAdapter(gameActivity, gameController.getMyPlayerId()); + layout.setAdapter(playerAdapter); }); } @@ -787,28 +468,18 @@ public void run() { */ @Override public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { case R.id.menu_abort: new AlertDialog.Builder(this) .setTitle(R.string.gamefield_abort_game) .setMessage(R.string.gamefield_abort_game_message) - .setPositiveButton(R.string.button_okay, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - showTextPopup(R.string.popup_title_abort, R.string.popup_text_abort); - runOnGameThread(new Runnable() { - @Override - public void run() { - serverGameController.abortGame(); - } - }, 3000); - - } + .setPositiveButton(R.string.button_okay, (dialog, which) -> { + showTextPopup(R.string.popup_title_abort, R.string.popup_text_abort); + runOnGameThread(() -> serverGameController.abortGame(), 3000); + }) - .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - // do nothing - } + .setNegativeButton(android.R.string.no, (dialog, which) -> { + // do nothing }) .setIcon(R.drawable.ic_close_black_24dp) .setCancelable(false) @@ -817,7 +488,6 @@ public void onClick(DialogInterface dialog, int which) { default: return super.onOptionsItemSelected(item); } - } /** @@ -828,25 +498,18 @@ public void onBackPressed() { new AlertDialog.Builder(this) .setTitle(R.string.gamefield_press_back) .setMessage(R.string.gamefield_press_back_message) - .setPositiveButton(R.string.button_okay, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - showTextPopup(R.string.popup_title_abort, R.string.popup_text_abort); - runOnGameThread(new Runnable() { - @Override - public void run() { - if (isHost) { - serverGameController.abortGame(); - } else { - gameController.abortGame(); - } - } - }, 3000); - } + .setPositiveButton(R.string.button_okay, (dialog, which) -> { + showTextPopup(R.string.popup_title_abort, R.string.popup_text_abort); + runOnGameThread(() -> { + if (isHost) { + serverGameController.abortGame(); + } else { + gameController.abortGame(); + } + }, 3000); }) - .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - // do nothing - } + .setNegativeButton(android.R.string.no, (dialog, which) -> { + // do nothing }) .setIcon(R.drawable.ic_close_black_24dp) .setCancelable(false) diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/HelpActivity.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/HelpActivity.java index c187c6b..bc3d27a 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/HelpActivity.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/HelpActivity.java @@ -1,7 +1,7 @@ package org.secuso.privacyfriendlywerwolf.activity; import android.os.Bundle; -import android.support.v7.widget.Toolbar; +import androidx.appcompat.widget.Toolbar; import android.widget.ExpandableListView; import org.secuso.privacyfriendlywerwolf.R; @@ -30,7 +30,7 @@ protected void onCreate(Bundle savedInstanceState) { ExpandableListAdapter expandableListAdapter; HelpDataDump helpDataDump = new HelpDataDump(this); - ExpandableListView generalExpandableListView = (ExpandableListView) findViewById(R.id.generalExpandableListView); + ExpandableListView generalExpandableListView = findViewById(R.id.generalExpandableListView); LinkedHashMap> expandableListDetail = helpDataDump.getDataGeneral(); List expandableListTitleGeneral = new ArrayList(expandableListDetail.keySet()); @@ -39,7 +39,7 @@ protected void onCreate(Bundle savedInstanceState) { overridePendingTransition(0, 0); - toolbar = (Toolbar) findViewById(R.id.toolbar); + toolbar = findViewById(R.id.toolbar); toolbar.setTitle(R.string.action_help); } diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/MainActivity.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/MainActivity.java index f463f01..618f9f1 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/MainActivity.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/MainActivity.java @@ -3,7 +3,7 @@ import android.content.Context; import android.content.Intent; import android.os.Bundle; -import android.support.v7.widget.Toolbar; +import androidx.appcompat.widget.Toolbar; import android.view.View; import android.widget.Button; @@ -11,7 +11,7 @@ import org.secuso.privacyfriendlywerwolf.dialog.PlayerInputDialog; /** - * Starting activiy when the game is fully loaded and tutorial is passed + * Starting activity when the game is fully loaded and tutorial is passed * * @author Florian Staubach */ @@ -26,24 +26,14 @@ protected void onCreate(Bundle savedInstanceState) { contextOfApplication = getApplicationContext(); setContentView(R.layout.activity_main); - Button buttonJoinGame = (Button) findViewById(R.id.game_button_join); - Button buttonNewGame = (Button) findViewById(R.id.game_button_start); + Button buttonJoinGame = findViewById(R.id.game_button_join); + Button buttonNewGame = findViewById(R.id.game_button_start); - buttonJoinGame.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - joinGame(view); - } - }); + buttonJoinGame.setOnClickListener(this::joinGame); - buttonNewGame.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - startNewGame(view); - } - }); + buttonNewGame.setOnClickListener(this::startNewGame); - toolbar = (Toolbar) findViewById(R.id.toolbar); + toolbar = findViewById(R.id.toolbar); toolbar.setTitle(R.string.action_main); } @@ -56,7 +46,7 @@ public void onClick(View view) { public void startNewGame(View view) { PlayerInputDialog playerInputDialog = new PlayerInputDialog(); playerInputDialog.setCancelable(false); - playerInputDialog.show(getFragmentManager(), "playerInputDialog"); + playerInputDialog.show(getSupportFragmentManager(), "playerInputDialog"); } /** diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/SettingsActivity.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/SettingsActivity.java index 532071b..3b7b9b2 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/SettingsActivity.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/SettingsActivity.java @@ -38,59 +38,53 @@ public class SettingsActivity extends BaseActivity { * A preference value change listener that updates the preference's summary * to reflect its new value. */ - private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object value) { - String stringValue = value.toString(); - - if (preference instanceof ListPreference) { - // For list preferences, look up the correct display value in - // the preference's 'entries' list. - ListPreference listPreference = (ListPreference) preference; - int index = listPreference.findIndexOfValue(stringValue); - - // Set the summary to reflect the new value. - preference.setSummary( - index >= 0 - ? listPreference.getEntries()[index] - : null); - } else if (preference instanceof NumberPickerPreference) { - NumberPickerPreference numPref = (NumberPickerPreference) preference; - Resources res = MainActivity.getContextOfApplication().getResources(); - if (numPref.getKey().equals(Constants.pref_werewolf_player)) { - preference.setSummary(res.getString(R.string.pref_werewolf_summary) + " " + stringValue); - } else if (numPref.getKey().startsWith(Constants.pref_timer_prefix)) { - preference.setSummary(res.getString(R.string.pref_timer_summary) + " " + stringValue + " " + res.getString(R.string.pref_seconds)); - } - - } else { - // For all other preferences, set the summary to the value's - // simple string representation. - preference.setSummary(stringValue); + private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = (preference, value) -> { + String stringValue = value.toString(); + + if (preference instanceof ListPreference) { + // For list preferences, look up the correct display value in + // the preference's 'entries' list. + ListPreference listPreference = (ListPreference) preference; + int index = listPreference.findIndexOfValue(stringValue); + + // Set the summary to reflect the new value. + preference.setSummary( + index >= 0 + ? listPreference.getEntries()[index] + : null); + } else if (preference instanceof NumberPickerPreference) { + NumberPickerPreference numPref = (NumberPickerPreference) preference; + Resources res = MainActivity.getContextOfApplication().getResources(); + if (numPref.getKey().equals(Constants.pref_werewolf_player)) { + preference.setSummary(res.getString(R.string.pref_werewolf_summary) + " " + stringValue); + } else if (numPref.getKey().startsWith(Constants.pref_timer_prefix)) { + preference.setSummary(res.getString(R.string.pref_timer_summary) + " " + stringValue + " " + res.getString(R.string.pref_seconds)); } - return true; + + } else { + // For all other preferences, set the summary to the value's + // simple string representation. + preference.setSummary(stringValue); } + return true; }; - private static SharedPreferences.OnSharedPreferenceChangeListener bindSharedPreferencesToGameContextListener = new SharedPreferences.OnSharedPreferenceChangeListener() { - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - switch (key) { - case Constants.pref_timer_day: - GameContext.getInstance().updateSetting(SettingsEnum.TIME_VILLAGER, String.valueOf(sharedPreferences.getInt(key, 300))); - break; - case Constants.pref_timer_night: - GameContext.getInstance().updateSetting(SettingsEnum.TIME_WEREWOLF, String.valueOf(sharedPreferences.getInt(key, 60))); - break; - case Constants.pref_timer_seer: - GameContext.getInstance().updateSetting(SettingsEnum.TIME_SEER, String.valueOf(sharedPreferences.getInt(key, 60))); - break; - case Constants.pref_timer_witch: - GameContext.getInstance().updateSetting(SettingsEnum.TIME_WITCH, String.valueOf(sharedPreferences.getInt(key, 60))); - break; - } - + private static SharedPreferences.OnSharedPreferenceChangeListener bindSharedPreferencesToGameContextListener = (sharedPreferences, key) -> { + switch (key) { + case Constants.pref_timer_day: + GameContext.getInstance().updateSetting(SettingsEnum.TIME_VILLAGER, String.valueOf(sharedPreferences.getInt(key, 300))); + break; + case Constants.pref_timer_night: + GameContext.getInstance().updateSetting(SettingsEnum.TIME_WEREWOLF, String.valueOf(sharedPreferences.getInt(key, 60))); + break; + case Constants.pref_timer_seer: + GameContext.getInstance().updateSetting(SettingsEnum.TIME_SEER, String.valueOf(sharedPreferences.getInt(key, 60))); + break; + case Constants.pref_timer_witch: + GameContext.getInstance().updateSetting(SettingsEnum.TIME_WITCH, String.valueOf(sharedPreferences.getInt(key, 60))); + break; } + }; /** @@ -222,8 +216,7 @@ protected boolean isValidFragment(String fragmentName) { * This fragment shows general preferences only. It is used when the * activity is showing a two-pane settings UI. */ - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public static class GeneralPreferenceFragment extends PreferenceFragment { + public static class GeneralPreferenceFragment extends PreferenceFragment { //TODO investigate androidx.preference @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/SplashActivity.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/SplashActivity.java index 217bedc..e270f5a 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/SplashActivity.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/SplashActivity.java @@ -1,7 +1,7 @@ package org.secuso.privacyfriendlywerwolf.activity; import android.content.Intent; -import android.support.v7.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; /** diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/StartClientActivity.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/StartClientActivity.java index 67a756d..5dcb31d 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/StartClientActivity.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/StartClientActivity.java @@ -5,12 +5,11 @@ import android.content.res.ColorStateList; import android.os.Bundle; import android.preference.PreferenceManager; -import android.support.v4.content.ContextCompat; -import android.support.v7.widget.Toolbar; +import androidx.core.content.ContextCompat; +import androidx.appcompat.widget.Toolbar; import android.text.TextUtils; import android.util.TypedValue; import android.view.View; -import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.LinearLayout; @@ -21,7 +20,6 @@ import org.secuso.privacyfriendlywerwolf.client.ClientGameController; import org.secuso.privacyfriendlywerwolf.dialog.TextDialog; import org.secuso.privacyfriendlywerwolf.helpers.PermissionHelper; -import org.secuso.privacyfriendlywerwolf.util.Constants; import java.util.Random; @@ -65,15 +63,15 @@ protected void onCreate(Bundle savedInstanceState) { String playerNameFromPref = sharedPref.getString(pref_playerName, ""); setContentView(R.layout.activity_start_client); - toolbar = (Toolbar) findViewById(R.id.toolbar); + toolbar = findViewById(R.id.toolbar); toolbar.setSubtitle(R.string.joingame_subtitle); - editTextAddress = (EditText) findViewById(R.id.address); - editTextPlayerName = (EditText) findViewById(playerName); + editTextAddress = findViewById(R.id.address); + editTextPlayerName = findViewById(playerName); editTextPlayerName.setText(playerNameFromPref); - buttonConnect = (Button) findViewById(R.id.connect); - textResponse = (TextView) findViewById(R.id.connecting); - loadingIndicator = (ProgressBar) findViewById(R.id.loading_indicator); + buttonConnect = findViewById(R.id.connect); + textResponse = findViewById(R.id.connecting); + loadingIndicator = findViewById(R.id.loading_indicator); gameController = ClientGameController.getInstance(); @@ -82,22 +80,17 @@ protected void onCreate(Bundle savedInstanceState) { waitingMode = false; // connect to the host - buttonConnect.setOnClickListener(new OnClickListener() { + buttonConnect.setOnClickListener(arg0 -> { + String url = editTextAddress.getText().toString(); + String playerName = editTextPlayerName.getText().toString(); + sharedPref.edit().putString(pref_playerName, playerName).apply(); - - @Override - public void onClick(View arg0) { - String url = editTextAddress.getText().toString(); - String playerName = editTextPlayerName.getText().toString(); - sharedPref.edit().putString(pref_playerName, playerName).apply(); - - if(TextUtils.isEmpty(editTextPlayerName.getText().toString())) { - playerName = getString(R.string.player_name_default) + " " + new Random().nextInt(1000); - } - - gameController.connect("ws://" + url + ":5000/ws", playerName); - deactivateConnectButton(); + if(TextUtils.isEmpty(editTextPlayerName.getText().toString())) { + playerName = getString(R.string.player_name_default) + " " + new Random().nextInt(1000); } + + gameController.connect("ws://" + url + ":5000/ws", playerName); + deactivateConnectButton(); }); PermissionHelper.showWifiAlert(this); @@ -129,11 +122,11 @@ public void deactivateConnectButton() { * therefore wait, if the user changed this fast) */ public void openConnectionFailedDialog() { - if (waitingMode == false) { + if (!waitingMode) { TextDialog textDialog = new TextDialog(); textDialog.setDialogTitle(getResources().getString(R.string.uh_dialog_title)); textDialog.setDialogText(getResources().getString(R.string.uh_dialog_text)); - textDialog.show(getFragmentManager(), "unknownHostDialog"); + textDialog.show(getSupportFragmentManager(), "unknownHostDialog"); activateConnectButton(); } } @@ -151,23 +144,18 @@ public void startGame() { */ public void showConnected() { waitingMode = true; - runOnUiThread(new Runnable() { - @Override - public void run() { - LinearLayout layout = (LinearLayout) findViewById(R.id.connectForm); - layout.removeAllViews(); - - TextView waitMessage = new TextView(getApplicationContext()); - waitMessage.setText(R.string.joingame_connected); - waitMessage.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); - waitMessage.setTextSize(TypedValue.COMPLEX_UNIT_PT, 10f); - waitMessage.setPadding(0, 50, 0, 0); - waitMessage.setTextColor(getResources().getColor(R.color.black)); - - layout.addView(waitMessage); - } + runOnUiThread(() -> { + LinearLayout layout = findViewById(R.id.connectForm); + layout.removeAllViews(); + + TextView waitMessage = new TextView(getApplicationContext()); + waitMessage.setText(R.string.joingame_connected); + waitMessage.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); + waitMessage.setTextSize(TypedValue.COMPLEX_UNIT_PT, 10f); + waitMessage.setPadding(0, 50, 0, 0); + waitMessage.setTextColor(getResources().getColor(R.color.black)); + + layout.addView(waitMessage); }); - } - } diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/StartHostActivity.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/StartHostActivity.java index e7710f1..1bce298 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/StartHostActivity.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/StartHostActivity.java @@ -1,10 +1,9 @@ package org.secuso.privacyfriendlywerwolf.activity; -import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; -import android.support.v7.app.AlertDialog; -import android.support.v7.widget.Toolbar; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.widget.Toolbar; import android.view.View; import android.widget.ArrayAdapter; import android.widget.Button; @@ -64,11 +63,11 @@ protected void onCreate(Bundle savedInstanceState) { serverGameController.destroy(); setContentView(R.layout.activity_start_host); - infoip = (TextView) findViewById(R.id.infoip); + infoip = findViewById(R.id.infoip); infoip.setText(getIpAddress()); - toolbar = (Toolbar) findViewById(R.id.toolbar); + toolbar = findViewById(R.id.toolbar); toolbar.setSubtitle(R.string.startgame_subtitle); PermissionHelper.showWifiAlert(this); @@ -78,7 +77,7 @@ protected void onCreate(Bundle savedInstanceState) { serverGameController.startServer(); - buttonStart = (Button) findViewById(R.id.btn_start); + buttonStart = findViewById(R.id.btn_start); // user clicks the button to start the game @@ -99,15 +98,9 @@ public void onClick(View view) { new AlertDialog.Builder(activity) .setTitle(R.string.startgame_need_players) .setMessage(R.string.startgame_need_players_message) - .setPositiveButton(R.string.button_okay, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - openGameInformationDialog(); - } - }) - .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - // just close and wait for more players - } + .setPositiveButton(R.string.button_okay, (dialog, which) -> openGameInformationDialog()) + .setNegativeButton(android.R.string.no, (dialog, which) -> { + // just close and wait for more players }) .setIcon(R.drawable.ic_face_black_24dp) .setCancelable(false) @@ -120,7 +113,7 @@ public void onClick(DialogInterface dialog, int which) { }.init(this)); - ListView list = (ListView) findViewById(R.id.host_player_list); + ListView list = findViewById(R.id.host_player_list); stringPlayers = new ArrayList<>(); @@ -137,7 +130,7 @@ private void openGameInformationDialog() { dialog.setAmountOfPlayers(stringPlayers.size()); dialog.setStartHostActivity(this); dialog.setCancelable(false); - dialog.show(getFragmentManager(), "gameInformationDialog"); + dialog.show(getSupportFragmentManager(), "gameInformationDialog"); } /** @@ -156,12 +149,7 @@ private void fillStringPlayers() { */ public void renderUI() { fillStringPlayers(); - runOnUiThread(new Runnable() { - @Override - public void run() { - playerAdapter.notifyDataSetChanged(); - } - }); + runOnUiThread(() -> playerAdapter.notifyDataSetChanged()); } @@ -197,7 +185,7 @@ private String getIpAddress() { } catch (SocketException e) { e.printStackTrace(); - ip += "Something Wrong! " + e.toString() + "\n"; + ip += "Something Wrong! " + e + "\n"; } return ip; diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/TutorialActivity.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/TutorialActivity.java index f6edecc..9b0cdf0 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/TutorialActivity.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/TutorialActivity.java @@ -4,11 +4,11 @@ import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Color; -import android.os.Build; import android.os.Bundle; -import android.support.v4.view.PagerAdapter; -import android.support.v4.view.ViewPager; -import android.support.v7.app.AppCompatActivity; +import androidx.annotation.NonNull; +import androidx.viewpager.widget.PagerAdapter; +import androidx.viewpager.widget.ViewPager; +import androidx.appcompat.app.AppCompatActivity; import android.text.Html; import android.view.LayoutInflater; import android.view.View; @@ -59,16 +59,14 @@ protected void onCreate(Bundle savedInstanceState) { } // Making notification bar transparent - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); - } + getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); setContentView(R.layout.activity_tutorial); - viewPager = (ViewPager) findViewById(R.id.view_pager); - dotsLayout = (LinearLayout) findViewById(R.id.layoutDots); - btnSkip = (Button) findViewById(R.id.btn_skip); - btnNext = (Button) findViewById(R.id.btn_next); + viewPager = findViewById(R.id.view_pager); + dotsLayout = findViewById(R.id.layoutDots); + btnSkip = findViewById(R.id.btn_skip); + btnNext = findViewById(R.id.btn_next); // layouts of all welcome sliders @@ -88,25 +86,17 @@ protected void onCreate(Bundle savedInstanceState) { viewPager.setAdapter(myViewPagerAdapter); viewPager.addOnPageChangeListener(viewPagerPageChangeListener); - btnSkip.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - launchHomeScreen(); - } - }); + btnSkip.setOnClickListener(v -> launchHomeScreen()); - btnNext.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - // checking for last page - // if last page home screen will be launched - int current = getItem(+1); - if (current < layouts.length) { - // move to next screen - viewPager.setCurrentItem(current); - } else { - launchHomeScreen(); - } + btnNext.setOnClickListener(v -> { + // checking for last page + // if last page home screen will be launched + int current = getItem(+1); + if (current < layouts.length) { + // move to next screen + viewPager.setCurrentItem(current); + } else { + launchHomeScreen(); } }); } @@ -182,25 +172,22 @@ public void onPageScrollStateChanged(int arg0) { * Making notification bar transparent */ private void changeStatusBarColor() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - Window window = getWindow(); - window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); - window.setStatusBarColor(Color.TRANSPARENT); - } + Window window = getWindow(); + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); + window.setStatusBarColor(Color.TRANSPARENT); } /** * View pager adapter */ public class MyViewPagerAdapter extends PagerAdapter { - private LayoutInflater layoutInflater; - public MyViewPagerAdapter() { } + @NonNull @Override - public Object instantiateItem(ViewGroup container, int position) { - layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); + public Object instantiateItem(@NonNull ViewGroup container, int position) { + LayoutInflater layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = layoutInflater.inflate(layouts[position], container, false); container.addView(view); @@ -214,15 +201,14 @@ public int getCount() { } @Override - public boolean isViewFromObject(View view, Object obj) { + public boolean isViewFromObject(@NonNull View view, @NonNull Object obj) { return view == obj; } @Override - public void destroyItem(ViewGroup container, int position, Object object) { - View view = (View) object; - container.removeView(view); + public void destroyItem(ViewGroup container, int position, @NonNull Object object) { + container.removeView((View) object); } } } diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/adapter/PlayerAdapter.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/adapter/PlayerAdapter.java index ebb78c8..f1da1e1 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/adapter/PlayerAdapter.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/adapter/PlayerAdapter.java @@ -23,9 +23,9 @@ */ public class PlayerAdapter extends BaseAdapter { - private Context context; - private List players; - private long myId; + private final Context context; + private final List players; + private final long myId; /** * Constructor @@ -88,11 +88,11 @@ public View getView(int position, View convertView, ViewGroup parent) { Player player = players.get(position); // set the label and button for the current player - TextView textView = (TextView) gridView + TextView textView = gridView .findViewById(R.id.player_item_label); textView.setText(player.getPlayerName()); - ImageButton playerButton = (ImageButton) gridView + ImageButton playerButton = gridView .findViewById(R.id.player_item_button); @@ -109,7 +109,7 @@ public View getView(int position, View convertView, ViewGroup parent) { // set click listener for all player buttons playerButton.setOnClickListener(new PlayerCardClickListener(GameContext.getInstance().getPlayerById(myId), player)); } else { - gridView = (View) convertView; + gridView = convertView; } return gridView; diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/client/ClientGameController.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/client/ClientGameController.java index 17c90dd..9cc2601 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/client/ClientGameController.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/client/ClientGameController.java @@ -20,7 +20,10 @@ import org.secuso.privacyfriendlywerwolf.util.ContextUtil; import org.secuso.privacyfriendlywerwolf.util.GameUtil; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.Random; /** @@ -30,7 +33,6 @@ * @author Florian Staubach */ public class ClientGameController { - private static final String TAG = "ClientGameController"; private static final ClientGameController GAME_CONTROLLER = new ClientGameController(); @@ -44,8 +46,7 @@ public class ClientGameController { private StartClientActivity startClientActivity; private GameActivity gameActivity; private WebsocketClientHandler websocketClientHandler; - private GameContext gameContext; - + private final GameContext gameContext; private ClientGameController() { Log.d(TAG, "ClientGameController singleton created"); @@ -56,12 +57,10 @@ private ClientGameController() { public static ClientGameController getInstance() { return GAME_CONTROLLER; - } // enter GameActivity public void startGame(GameContext gc) { - gameContext.copy(gc); startClientActivity.startGame(); //wait some time before the game activity has been created @@ -73,8 +72,6 @@ public void startGame(GameContext gc) { gameActivity.outputMessage(R.string.progressBar_initial); gameActivity.longOutputMessage(R.string.gameStart_hintRoles); - - } @@ -82,7 +79,6 @@ public void startGame(GameContext gc) { * Everybody goes to sleep and the werewolves awake. */ public void initiateWerewolfPhase() { - ContextUtil.END_OF_ROUND = false; Player ownPlayer = GameContext.getInstance().getPlayerById(myId); @@ -196,28 +192,21 @@ public void initiateWerewolfPhase() { } } - if (gameContext.getPlayerById(myId).getPlayerRole() == Player.Role.WEREWOLF && !ownPlayer.isDead()) { gameActivity.longOutputMessage(R.string.toast_prepare_vote); - } sendDoneToServer(); - } /** * The werewolves do a voting for their prey */ public void initiateWerewolfVotingPhase() { - // soft timer - gameActivity.runOnUiThread(new Runnable() { - @Override - public void run() { - int time = Integer.parseInt(gameContext.getSetting(SettingsEnum.TIME_WEREWOLF)); - gameActivity.makeTimer(time).start(); - } + gameActivity.runOnUiThread(() -> { + int time = Integer.parseInt(gameContext.getSetting(SettingsEnum.TIME_WEREWOLF)); + gameActivity.makeTimer(time).start(); }); // Host @@ -243,7 +232,6 @@ public void run() { * The werewolves finished voting and go back to sleep */ public void endWerewolfPhase() { - gameActivity.outputMessage(R.string.message_werewolfes_sleep); Player ownPlayer = GameContext.getInstance().getPlayerById(myId); @@ -253,7 +241,7 @@ public void endWerewolfPhase() { gameActivity.setMediaPlayer(MediaPlayer.create(gameActivity.getApplicationContext(), R.raw.wolves_sleep)); gameActivity.getMediaPlayer().start(); } - Player roundVictim = getPlayerKilledByWerewolfesName(); + Player roundVictim = getPlayerKilledByWerewolvesName(); // Werewolf and (living or voted for himself) if (gameContext.getPlayerById(myId).getPlayerRole() == Player.Role.WEREWOLF @@ -271,7 +259,6 @@ public void endWerewolfPhase() { Log.e(TAG, "D/THREAD_Problem: " + e.getMessage()); } - sendDoneToServer(); } @@ -279,15 +266,12 @@ public void endWerewolfPhase() { * The witch awakes, and gets to use her healing potion. */ public void initiateWitchElixirPhase() { - Player roundVictim = getPlayerKilledByWerewolfesName(); + Player roundVictim = getPlayerKilledByWerewolvesName(); if (GameUtil.isWitchAlive() || (roundVictim != null && roundVictim.getPlayerRole() == Player.Role.WITCH)) { gameActivity.outputMessage(R.string.message_witch_awaken); - gameActivity.runOnUiThread(new Runnable() { - @Override - public void run() { - int time = Integer.parseInt(gameContext.getSetting(SettingsEnum.TIME_WITCH)); - gameActivity.makeTimer(time).start(); - } + gameActivity.runOnUiThread(() -> { + int time = Integer.parseInt(gameContext.getSetting(SettingsEnum.TIME_WITCH)); + gameActivity.makeTimer(time).start(); }); // Host @@ -300,7 +284,7 @@ public void run() { if (gameContext.getPlayerById(myId).getPlayerRole().equals(Player.Role.WITCH)) { StringBuilder sb = new StringBuilder(); sb.append(gameActivity.getString(R.string.gamefield_witch_elixir_action_message1)); - Player victim = getPlayerKilledByWerewolfesName(); + Player victim = getPlayerKilledByWerewolvesName(); if (victim != null) { sb.append(" "); sb.append(victim.getPlayerName()); @@ -387,9 +371,8 @@ public void endWitchElixirPhase() { // ask the witch to use her poisoning potion public void initiateWitchPoisonPhase() { - Log.d(TAG, "initiating WitchPoisonPhase()"); - Player roundVictim = getPlayerKilledByWerewolfesName(); + Player roundVictim = getPlayerKilledByWerewolvesName(); if (GameUtil.isWitchAlive() || (roundVictim != null && roundVictim.getPlayerRole() == Player.Role.WITCH)) { if (myId == Constants.SERVER_PLAYER_ID && gameActivity.getMediaPlayer() != null) { // prevent music overlays @@ -431,13 +414,7 @@ public void initiateWitchPoisonPhase() { } sendDoneToServer(); } - - } else - - { - sendDoneToServer(); - } - + } else sendDoneToServer(); } // computing the result of the poisoning phase @@ -463,25 +440,20 @@ public void endWitchPoisonPhase() { e.printStackTrace(); } } - - } /** * The seer wakes and gets to know a secret identity */ public void initiateSeerPhase() { - Player roundVictim = getPlayerKilledByWerewolfesName(); + Player roundVictim = getPlayerKilledByWerewolvesName(); Player witchVictim = getPlayerKilledByWitchName(); if (GameUtil.isSeerAlive() || (roundVictim != null && roundVictim.getPlayerRole() == Player.Role.SEER) || (witchVictim != null && witchVictim.getPlayerRole() == Player.Role.SEER)) { - gameActivity.runOnUiThread(new Runnable() { - @Override - public void run() { - int time = Integer.parseInt(gameContext.getSetting(SettingsEnum.TIME_SEER)); - gameActivity.makeTimer(time).start(); - } + gameActivity.runOnUiThread(() -> { + int time = Integer.parseInt(gameContext.getSetting(SettingsEnum.TIME_SEER)); + gameActivity.makeTimer(time).start(); }); gameActivity.outputMessage(R.string.message_seer_awaken); if (myId == Constants.SERVER_PLAYER_ID && gameActivity.getMediaPlayer() != null) { @@ -528,7 +500,7 @@ public void run() { // seer goes back to sleep public void endSeerPhase() { - Player roundVictim = getPlayerKilledByWerewolfesName(); + Player roundVictim = getPlayerKilledByWerewolvesName(); Player witchVictim = getPlayerKilledByWitchName(); if (GameUtil.isSeerAlive() || (roundVictim != null && roundVictim.getPlayerRole() == Player.Role.SEER) @@ -556,8 +528,7 @@ public void endSeerPhase() { * Wait for nextButton trigger, to start the voting. */ public void initiateDayPhase() { - final Player killedPlayer = GameContext.getInstance().getPlayerById(ContextUtil.lastKilledPlayerID); - final Player killedByWitchPlayer = GameContext.getInstance().getPlayerById(ContextUtil.lastKilledPlayerIDByWitch); + List killedPlayers = getKilledPlayers(); Player ownPlayer = GameContext.getInstance().getPlayerById(myId); // reset variables @@ -567,8 +538,9 @@ public void initiateDayPhase() { gameActivity.outputMessage(R.string.message_villagers_awaken); Log.d(TAG, "Before day_wakes: " + Thread.currentThread().getName()); - if (myId == Constants.SERVER_PLAYER_ID && gameActivity.getMediaPlayer() != null) { + + if (myId == Constants.SERVER_PLAYER_ID && gameActivity.getMediaPlayer() != null) { gameActivity.setMediaPlayer(MediaPlayer.create(gameActivity.getApplicationContext(), R.raw.day_wakes)); gameActivity.getMediaPlayer().start(); @@ -588,27 +560,10 @@ public void initiateDayPhase() { } // voice output first tells players how many players died in the night - if (killedPlayer == null && killedByWitchPlayer == null) { - gameActivity.setMediaPlayer(MediaPlayer.create(gameActivity.getApplicationContext(), R.raw.day_none_died)); - gameActivity.getMediaPlayer().start(); - } else if (killedPlayer != null && killedByWitchPlayer == null) { - gameActivity.setMediaPlayer(MediaPlayer.create(gameActivity.getApplicationContext(), R.raw.day_one_died)); - gameActivity.getMediaPlayer().start(); - } else if (killedPlayer == null && killedByWitchPlayer != null) { - gameActivity.setMediaPlayer(MediaPlayer.create(gameActivity.getApplicationContext(), R.raw.day_one_died)); - gameActivity.getMediaPlayer().start(); - } else if (killedPlayer != null && killedByWitchPlayer != null) { - if (!(killedPlayer.getPlayerName().equals(killedByWitchPlayer.getPlayerName()))) { - gameActivity.setMediaPlayer(MediaPlayer.create(gameActivity.getApplicationContext(), R.raw.day_two_died)); - gameActivity.getMediaPlayer().start(); - } else { - gameActivity.setMediaPlayer(MediaPlayer.create(gameActivity.getApplicationContext(), R.raw.day_one_died)); - gameActivity.getMediaPlayer().start(); - } - } else { - Log.d(TAG, "initiateDayPhase(): Something went wrong here"); - } - + //TODO support more than two deaths (needed for more roles) + final int clip = killedPlayers.isEmpty() ? R.raw.day_none_died : killedPlayers.size() == 1 ? R.raw.day_one_died : R.raw.day_two_died; + gameActivity.setMediaPlayer(MediaPlayer.create(gameActivity.getApplicationContext(), clip)); + gameActivity.getMediaPlayer().start(); } else { try { Thread.sleep(9100); @@ -631,38 +586,19 @@ public void initiateDayPhase() { } // show players on the UI who died in the night - if (killedPlayer == null && killedByWitchPlayer == null) { + if (killedPlayers.isEmpty()) { gameActivity.showTextPopup(R.string.popup_title_victims, R.string.popup_text_none_died); - } else if (killedPlayer != null && killedByWitchPlayer == null) { - gameActivity.showTextPopup(R.string.popup_title_victims, killedPlayer.getPlayerName() + " (" + gameActivity.getResources().getString(killedPlayer.getPlayerRole().getRole()) + ")", R.string.popup_text_killed_this_night); - } else if (killedPlayer == null && killedByWitchPlayer != null) { - gameActivity.showTextPopup(R.string.popup_title_victims, killedByWitchPlayer.getPlayerName() + " (" + gameActivity.getResources().getString(killedByWitchPlayer.getPlayerRole().getRole()) + ")", R.string.popup_text_killed_this_night); - } else if (killedPlayer != null && killedByWitchPlayer != null) { - if (!(killedPlayer.getPlayerName().equals(killedByWitchPlayer.getPlayerName()))) { - Log.d(TAG, "Two died: random generated the num " + ContextUtil.RANDOM_INDEX); - Player firstVictim = null; - Player secondVictim = null; - if (ContextUtil.RANDOM_INDEX == 0) { - firstVictim = killedPlayer; - secondVictim = killedByWitchPlayer; - } else if (ContextUtil.RANDOM_INDEX == 1) { - firstVictim = killedByWitchPlayer; - secondVictim = killedPlayer; - } else { - Log.d(TAG, "Something went wrong with random"); - firstVictim = new Player("PLAYER_NOT_EXIST"); - firstVictim.setPlayerRole(Player.Role.CITIZEN); - secondVictim = new Player("PLAYER_NOT_EXIST"); - secondVictim.setPlayerRole(Player.Role.CITIZEN); - } - ContextUtil.RANDOM_INDEX = -1; - gameActivity.showTextPopup(R.string.popup_title_victims, firstVictim.getPlayerName() + " (" + gameActivity.getResources().getString(firstVictim.getPlayerRole().getRole()) + ")" - + " & " + secondVictim.getPlayerName() + " (" + gameActivity.getResources().getString(secondVictim.getPlayerRole().getRole()) + ")", R.string.popup_text_killed_this_night_2); - } else { - // players killed twice, only show once - Log.d(TAG, "initiateDayPhase(): Somehow the same player got killed twice"); - gameActivity.showTextPopup(R.string.popup_title_victims, killedPlayer.getPlayerName() + " (" + gameActivity.getResources().getString(killedPlayer.getPlayerRole().getRole()) + ")", R.string.popup_text_killed_this_night); + } else if (killedPlayers.size() == 1) { + Player killed = killedPlayers.get(0); + gameActivity.showTextPopup(R.string.popup_title_victims, R.string.popup_text_killed_this_night, killed.getPlayerName(), gameActivity.getResources().getString(killed.getPlayerRole().getRole())); + } else { + StringBuilder playerListLeft = new StringBuilder(); + Player lastPlayer = killedPlayers.remove(killedPlayers.size() - 1); + for (Player player : killedPlayers) { + if (playerListLeft.length() > 0) playerListLeft.append(", "); + playerListLeft.append(player.getPlayerName()).append(" (").append(gameActivity.getResources().getString(player.getPlayerRole().getRole())).append(")"); } + gameActivity.showTextPopup(R.string.popup_title_victims, R.string.popup_text_killed_this_night_2, playerListLeft.toString(), lastPlayer.getPlayerName(), gameActivity.getResources().getString(lastPlayer.getPlayerRole().getRole())); } gameActivity.updateGamefield(); @@ -683,12 +619,9 @@ public void initiateDayPhase() { gameActivity.longOutputMessage(R.string.toast_start_discussion); } gameActivity.outputMessage(R.string.message_villagers_discuss); - gameActivity.runOnUiThread(new Runnable() { - @Override - public void run() { - int time = Integer.parseInt(gameContext.getSetting(SettingsEnum.TIME_VILLAGER)); - gameActivity.makeTimer(time).start(); - } + gameActivity.runOnUiThread(() -> { + int time = Integer.parseInt(gameContext.getSetting(SettingsEnum.TIME_VILLAGER)); + gameActivity.makeTimer(time).start(); }); ContextUtil.END_OF_ROUND = true; if (myId == Constants.SERVER_PLAYER_ID) { @@ -701,7 +634,21 @@ public void run() { } /** - * Werewolves win if the number of werwolves is + * Gets the list of players killed in the current night + */ + private List getKilledPlayers() { + //TODO don't send details about the death source to the client + final Player killedPlayer = GameContext.getInstance().getPlayerById(ContextUtil.lastKilledPlayerID); + final Player killedByWitchPlayer = GameContext.getInstance().getPlayerById(ContextUtil.lastKilledPlayerIDByWitch); + List killedPlayers = new ArrayList<>(); + if (killedPlayer != null) killedPlayers.add(killedPlayer); + if (killedByWitchPlayer != null) killedPlayers.add(killedByWitchPlayer); + Collections.shuffle(killedPlayers); + return killedPlayers; + } + + /** + * Werewolves win if the number of werewolves is * greater or equal than the number of citizens */ private void endGameAndWerewolvesWin() { @@ -726,12 +673,9 @@ private void endGameAndWerewolvesWin() { } // indicator for the players as to when the game will exit - gameActivity.runOnUiThread(new Runnable() { - @Override - public void run() { - int time = 15; - gameActivity.makeTimer(time).start(); - } + gameActivity.runOnUiThread(() -> { + int time = 15; + gameActivity.makeTimer(time).start(); }); try { @@ -771,12 +715,9 @@ private void endGameAndVillagersWin() { } // indicator for the players as to when the game will exit - gameActivity.runOnUiThread(new Runnable() { - @Override - public void run() { - int time = 15; - gameActivity.makeTimer(time).start(); - } + gameActivity.runOnUiThread(() -> { + int time = 15; + gameActivity.makeTimer(time).start(); }); try { @@ -784,7 +725,7 @@ public void run() { } catch (InterruptedException e) { Log.e(TAG, "D/THREAD_Problem: " + e.getMessage()); } - // reset everything, that needs to be resetted + // reset the controllers state destroy(); // go back to main menu gameActivity.goToMainActivity(); @@ -877,7 +818,7 @@ else if (werewolfCount == 0) { public void useElixir() { if (gameContext.getSetting(SettingsEnum.WITCH_ELIXIR) == null) { - gameActivity.askWitchForElixir(); + gameActivity.showWitchElixirPopup(); } else { sendDoneToServer(); } @@ -885,7 +826,7 @@ public void useElixir() { public void usePoison() { if (gameContext.getSetting(SettingsEnum.WITCH_POISON) == null) { - gameActivity.askWitchForPoison(); + gameActivity.showWitchPoisonPopup(); } else { sendDoneToServer(); } @@ -948,7 +889,7 @@ public void sendVotingResult(Player player) { serverGameController.handleVotingResult(Constants.EMPTY_VOTING_PLAYER); } else { try { - NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE.VOTING_RESULT); + NetworkPackage np = new NetworkPackage<>(NetworkPackage.PACKAGE_TYPE.VOTING_RESULT); np.setPayload(""); websocketClientHandler.send(np); } catch (Exception e) { @@ -1030,7 +971,7 @@ public void connectionFailed(){ * * @return the player object which got killed */ - public Player getPlayerKilledByWerewolfesName() { + public Player getPlayerKilledByWerewolvesName() { //Long id = Long.getLong(gameContext.getSetting(SettingsEnum.KILLED_BY_WEREWOLF)); //String id = gameContext.getSetting(SettingsEnum.KILLED_BY_WEREWOLF); Long id = ContextUtil.lastKilledPlayerID; @@ -1065,20 +1006,20 @@ public Player getPlayerKilledByWitchName() { */ public void sendDoneToServer() { // if not the host - if (myId != 0) { - try { - NetworkPackage np = new NetworkPackage<>(NetworkPackage.PACKAGE_TYPE.DONE); - websocketClientHandler.send(np); - } catch (Exception e) { - e.printStackTrace(); - } - } else if (myId == 0) { + if (myId == 0) { Log.d(TAG, "Host is now done!"); ServerGameController.HOST_IS_DONE = true; // startNextPhase when all Clients are ready as well if (ServerGameController.CLIENTS_ARE_DONE) { serverGameController.startNextPhase(); } + } else { + try { + NetworkPackage np = new NetworkPackage<>(NetworkPackage.PACKAGE_TYPE.DONE); + websocketClientHandler.send(np); + } catch (Exception e) { + e.printStackTrace(); + } } } @@ -1174,7 +1115,6 @@ public void abortGame() { * After this you are able to start a new game without any old data */ public void destroy() { - gameContext.destroy(); ContextUtil.destroy(); if(websocketClientHandler != null) { diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/client/WebsocketClientHandler.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/client/WebsocketClientHandler.java index 45d236f..ec149ee 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/client/WebsocketClientHandler.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/client/WebsocketClientHandler.java @@ -207,8 +207,8 @@ public void run() { break; case PHASE_DAY_START: Log.d(TAG, "Client: Starting DayPhase"); - String randomNumberString = np.getOption("random number"); - ContextUtil.RANDOM_INDEX = Integer.parseInt(randomNumberString); +// String randomNumberString = np.getOption("random number"); +// ContextUtil.RANDOM_INDEX = Integer.parseInt(randomNumberString); gameController.initiateDayPhase(); break; case PHASE_DAY_END: diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/context/GameContext.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/context/GameContext.java index 4df564d..af5cef9 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/context/GameContext.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/context/GameContext.java @@ -33,7 +33,7 @@ public class GameContext { private static final GameContext GAME_CONTEXT = new GameContext(); - private List players = new ArrayList(); + private List players = new ArrayList<>(); private Map settings = new HashMap<>(); private GamePhaseEnum currentPhase; diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/dialog/GameInformationDialog.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/dialog/GameInformationDialog.java index 159c98f..1edb6e8 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/dialog/GameInformationDialog.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/dialog/GameInformationDialog.java @@ -2,12 +2,13 @@ import android.app.AlertDialog; import android.app.Dialog; -import android.app.DialogFragment; -import android.content.DialogInterface; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.PreferenceManager; +import androidx.annotation.NonNull; +import androidx.fragment.app.DialogFragment; + import org.secuso.privacyfriendlywerwolf.R; import org.secuso.privacyfriendlywerwolf.activity.MainActivity; import org.secuso.privacyfriendlywerwolf.activity.StartHostActivity; @@ -25,7 +26,7 @@ public class GameInformationDialog extends DialogFragment { private int amountOfPlayers; private float margin = 0; - + @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // Use the Builder class for convenient dialog construction @@ -51,19 +52,12 @@ public Dialog onCreateDialog(Bundle savedInstanceState) { + System.lineSeparator() + System.lineSeparator() + getResources().getString(R.string.popup_input_correct) + System.lineSeparator()) - .setPositiveButton(R.string.button_okay, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - startHostActivity.startGame(); - } - }) - .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - // TODO: is this necessary? Just do nothing here. - dialog.dismiss(); - } + .setPositiveButton(R.string.button_okay, (dialog, id) -> startHostActivity.startGame()) + .setNegativeButton(android.R.string.no, (dialog, id) -> { + // TODO: is this necessary? Just do nothing here. + dialog.dismiss(); }); - // Create the AlertDialog object and return it AlertDialog dialog = builder.create(); dialog.getWindow().getAttributes().verticalMargin = margin; @@ -99,5 +93,4 @@ public void setAmountOfPlayers(int amountOfPlayers) { public void setStartHostActivity(StartHostActivity startHostActivity) { this.startHostActivity = startHostActivity; } - } diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/dialog/PlayerInputDialog.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/dialog/PlayerInputDialog.java index 12b9240..a57a405 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/dialog/PlayerInputDialog.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/dialog/PlayerInputDialog.java @@ -2,18 +2,17 @@ import android.app.AlertDialog; import android.app.Dialog; -import android.app.DialogFragment; -import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.PreferenceManager; +import androidx.annotation.NonNull; +import androidx.fragment.app.DialogFragment; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.widget.EditText; -import org.secuso.privacyfriendlywerwolf.BuildConfig; import org.secuso.privacyfriendlywerwolf.R; import org.secuso.privacyfriendlywerwolf.activity.MainActivity; import org.secuso.privacyfriendlywerwolf.activity.StartHostActivity; @@ -33,6 +32,7 @@ public class PlayerInputDialog extends DialogFragment { private EditText userInput; private SharedPreferences sharedPref; + @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // Use the Builder class for convenient dialog construction @@ -52,32 +52,28 @@ public Dialog onCreateDialog(Bundle savedInstanceState) { .setTitle(R.string.playerNameInput_title) .setMessage(R.string.playerNameInput_text) .setPositiveButton(R.string.button_okay, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - Intent intent = new Intent(getActivity(), StartHostActivity.class); + (dialog, id) -> { + Intent intent = new Intent(getActivity(), StartHostActivity.class); - if(TextUtils.isEmpty(userInput.getText().toString())) { - intent.putExtra(Constants.PLAYERNAME_PUTEXTRA, getString(R.string.player_name_default) + " " + new Random().nextInt(1000)); - } else { - intent.putExtra(Constants.PLAYERNAME_PUTEXTRA, userInput.getText().toString()); - } - - sharedPref.edit().putString(pref_playerName, userInput.getText().toString()).apply(); - startActivity(intent); + if(TextUtils.isEmpty(userInput.getText().toString())) { + intent.putExtra(Constants.PLAYERNAME_PUTEXTRA, getString(R.string.player_name_default) + " " + new Random().nextInt(1000)); + } else { + intent.putExtra(Constants.PLAYERNAME_PUTEXTRA, userInput.getText().toString()); } + + sharedPref.edit().putString(pref_playerName, userInput.getText().toString()).apply(); + startActivity(intent); }) .setNegativeButton(android.R.string.no, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - // go back to main menu if called from the navigation drawer - if(getTag().equals("dialog_from_drawer")) { - Intent intent = new Intent(getActivity(), MainActivity.class); - // erase backstack (pressing back-button now leads to home screen) - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); - intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); - startActivity(intent); - } + (dialog, id) -> { + // go back to main menu if called from the navigation drawer + if(getTag().equals("dialog_from_drawer")) { + Intent intent = new Intent(getActivity(), MainActivity.class); + // erase backstack (pressing back-button now leads to home screen) + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); + intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); + startActivity(intent); } }); diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/dialog/TextDialog.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/dialog/TextDialog.java index 304b5a8..10ed0ce 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/dialog/TextDialog.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/dialog/TextDialog.java @@ -2,10 +2,11 @@ import android.app.AlertDialog; import android.app.Dialog; -import android.app.DialogFragment; -import android.content.DialogInterface; import android.os.Bundle; +import androidx.annotation.NonNull; +import androidx.fragment.app.DialogFragment; + import org.secuso.privacyfriendlywerwolf.R; /** @@ -16,12 +17,12 @@ * @author Tobias Kowalski */ public class TextDialog extends DialogFragment { - private String dialogTitle; private String dialogText; private float margin = 0; + @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // Use the Builder class for convenient dialog construction @@ -30,14 +31,10 @@ public Dialog onCreateDialog(Bundle savedInstanceState) { builder.setTitle(dialogTitle) .setMessage(dialogText) - .setPositiveButton(R.string.button_okay, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { + .setPositiveButton(R.string.button_okay, (dialog, id) -> { - } }); - - // Create the AlertDialog object and return it AlertDialog dialog = builder.create(); dialog.getWindow().getAttributes().verticalMargin = margin; @@ -56,5 +53,4 @@ public void setDialogText(String dialogText) { public void setMargin(float margin) { this.margin = margin; } - } diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/dialog/VotingDialog.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/dialog/VotingDialog.java index 4dd46e8..d222952 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/dialog/VotingDialog.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/dialog/VotingDialog.java @@ -2,12 +2,14 @@ import android.app.AlertDialog; import android.app.Dialog; -import android.app.DialogFragment; import android.content.DialogInterface; import android.os.Bundle; import android.util.Log; import android.widget.ArrayAdapter; +import androidx.annotation.NonNull; +import androidx.fragment.app.DialogFragment; + import org.secuso.privacyfriendlywerwolf.R; import org.secuso.privacyfriendlywerwolf.client.ClientGameController; import org.secuso.privacyfriendlywerwolf.context.GameContext; @@ -21,7 +23,6 @@ * @author Tobias Kowalski */ public class VotingDialog extends DialogFragment { - private static final String TAG = "VotingDialog"; //TODO: use custom Player Adapter @@ -29,7 +30,7 @@ public class VotingDialog extends DialogFragment { private ArrayList stringPlayers; private ClientGameController gameController; - + @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // Use the Builder class for convenient dialog construction @@ -39,24 +40,14 @@ public Dialog onCreateDialog(Bundle savedInstanceState) { playerAdapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1, stringPlayers); builder.setTitle(R.string.voting_title) - .setAdapter(playerAdapter, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - //TODO: use a correct playerAdapter to get by id - String playerName = stringPlayers.get(which); - final Player player = GameContext.getInstance().getPlayerByName(playerName); + .setAdapter(playerAdapter, (dialog, which) -> { + //TODO: use a correct playerAdapter to get by id + String playerName = stringPlayers.get(which); + final Player player = GameContext.getInstance().getPlayerByName(playerName); - gameController.getGameActivity().runOnGameThread(new Runnable() { - @Override - public void run() { - gameController.sendVotingResult(player); - } - }, 0); - - - } + gameController.getGameActivity().runOnGameThread(() -> gameController.sendVotingResult(player), 0); }); - // Create the AlertDialog object and return it return builder.create(); } @@ -71,7 +62,7 @@ private void fillStringPlayers(){ } @Override - public void onCancel(DialogInterface dialog) { + public void onCancel(@NonNull DialogInterface dialog) { super.onCancel(dialog); // if somehow cancelled without voting, reopen dialog Log.d(TAG, "OnCancel(): You just cancelled the VOTING_Popup without voting, vote again!"); diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/dialog/WitchDialog.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/dialog/WitchDialog.java index ebc2b4f..ba108db 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/dialog/WitchDialog.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/dialog/WitchDialog.java @@ -2,11 +2,13 @@ import android.app.AlertDialog; import android.app.Dialog; -import android.app.DialogFragment; import android.content.DialogInterface; import android.os.Bundle; import android.util.Log; +import androidx.annotation.NonNull; +import androidx.fragment.app.DialogFragment; + import org.secuso.privacyfriendlywerwolf.R; import org.secuso.privacyfriendlywerwolf.activity.GameActivity; import org.secuso.privacyfriendlywerwolf.client.ClientGameController; @@ -15,7 +17,6 @@ * Created by Daniel on 13.02.2017. */ public class WitchDialog extends DialogFragment { - private static final String TAG = "WitchDialog"; private String dialogTitle; @@ -31,6 +32,7 @@ public static WitchDialog newInstance(int elixir) { return frag; } + @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { gameController = ClientGameController.getInstance(); @@ -39,20 +41,12 @@ public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog dialog = new AlertDialog.Builder(getActivity()) .setTitle(dialogTitle) .setMessage(dialogText) - .setPositiveButton(R.string.button_okay, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - // use the elixir - ((GameActivity) getActivity()).doPositiveClick(elixir); - } + .setPositiveButton(R.string.button_okay, (dialog12, which) -> { + // use the elixir + ((GameActivity) getActivity()).doPositiveClick(elixir); }) // do not use the elixir - .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - ((GameActivity) getActivity()).doNegativeClick(elixir); - } - }) + .setNegativeButton(android.R.string.no, (dialog1, which) -> ((GameActivity) getActivity()).doNegativeClick(elixir)) .setIcon(R.drawable.ic_local_drink_black_24dp) .create(); @@ -71,15 +65,15 @@ public void setDialogText(String dialogText) { } @Override - public void onCancel(DialogInterface dialog) { + public void onCancel(@NonNull DialogInterface dialog) { super.onCancel(dialog); // if somehow cancelld without answering, reopen the dialog if (dialogTitle.equals(getResources().getString(R.string.gamefield_witch_elixir_action))) { Log.d(TAG, "OnCancel(): You just cancelled the ELIXIR_Popup without answering, answer again!"); - gameController.getGameActivity().showWitchElixirPopup(dialogTitle, dialogText); + gameController.getGameActivity().showWitchElixirPopup(); } else if (dialogTitle.equals(getResources().getString(R.string.gamefield_witch_poison_action))) { Log.d(TAG, "OnCancel(): You just cancelled the POISON_Popup without answering, answer again!"); - gameController.getGameActivity().showWitchPoisonPopup(dialogTitle, dialogText); + gameController.getGameActivity().showWitchPoisonPopup(); } else { Log.d(TAG, "OnCancel(): Something went wrong here!"); } diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/ExpandableListAdapter.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/ExpandableListAdapter.java index 292c45c..7c88f14 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/ExpandableListAdapter.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/ExpandableListAdapter.java @@ -18,10 +18,9 @@ * last access 27th October 2016 */ public class ExpandableListAdapter extends BaseExpandableListAdapter { - - private Context context; - private List expandableListTitle; - private HashMap> expandableListDetail; + private final Context context; + private final List expandableListTitle; + private final HashMap> expandableListDetail; public ExpandableListAdapter(Context context, List expandableListTitle, HashMap> expandableListDetail) { @@ -50,7 +49,7 @@ public View getChildView(int listPosition, final int expandedListPosition, .getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = layoutInflater.inflate(R.layout.list_item, null); } - TextView expandedListTextView = (TextView) convertView + TextView expandedListTextView = convertView .findViewById(R.id.expandedListItem); expandedListTextView.setText(expandedListText); return convertView; @@ -58,8 +57,7 @@ public View getChildView(int listPosition, final int expandedListPosition, @Override public int getChildrenCount(int listPosition) { - return this.expandableListDetail.get(this.expandableListTitle.get(listPosition)) - .size(); + return this.expandableListDetail.get(this.expandableListTitle.get(listPosition)).size(); } @Override @@ -86,7 +84,7 @@ public View getGroupView(int listPosition, boolean isExpanded, getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = layoutInflater.inflate(R.layout.list_group, null); } - TextView listTitleTextView = (TextView) convertView + TextView listTitleTextView = convertView .findViewById(R.id.listTitle); listTitleTextView.setTypeface(null, Typeface.BOLD); listTitleTextView.setText(listTitle); diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/HelpDataDump.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/HelpDataDump.java index 055c658..3032cbb 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/HelpDataDump.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/HelpDataDump.java @@ -13,8 +13,7 @@ * last access 27th October 2016 */ public class HelpDataDump { - - private Context context; + private final Context context; public HelpDataDump(Context context) { this.context = context; @@ -65,5 +64,4 @@ public LinkedHashMap> getDataGeneral() { return expandableListDetail; } - } diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/PermissionHelper.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/PermissionHelper.java index 00a8f7f..6ff46b5 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/PermissionHelper.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/PermissionHelper.java @@ -1,22 +1,16 @@ package org.secuso.privacyfriendlywerwolf.helpers; -import android.Manifest; -import android.app.Activity; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; import android.net.wifi.WifiManager; -import android.support.v4.app.ActivityCompat; -import android.support.v4.content.ContextCompat; -import android.support.v7.app.AlertDialog; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; +import androidx.appcompat.app.AlertDialog; import org.secuso.privacyfriendlywerwolf.R; import org.secuso.privacyfriendlywerwolf.activity.MainActivity; -import java.util.List; - /** * PermissionHelper offers methods to check permissions and if they are not granted it will * show a notification to the user to grant the permissions diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/PlayerCardClickListener.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/PlayerCardClickListener.java index 06ae868..d7c39f6 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/PlayerCardClickListener.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/PlayerCardClickListener.java @@ -1,7 +1,7 @@ package org.secuso.privacyfriendlywerwolf.helpers; import android.content.DialogInterface; -import android.support.v7.app.AlertDialog; +import androidx.appcompat.app.AlertDialog; import android.util.Log; import android.view.View; import android.widget.Toast; @@ -49,11 +49,11 @@ public void onClick(final View view) { && ( // looking at the person that got killed by the Werewolves: // if the Werwolves killed no one this round (cant really happen, but for consistency) - ((clientGameController.getPlayerKilledByWerewolfesName() == null) || + ((clientGameController.getPlayerKilledByWerewolvesName() == null) || // if the Werwolves killed a person this round - (clientGameController.getPlayerKilledByWerewolfesName() != null + (clientGameController.getPlayerKilledByWerewolvesName() != null // if this person is not the clicked player.. - && (!clientGameController.getPlayerKilledByWerewolfesName().getPlayerName().equals(card.getPlayerName())))) + && (!clientGameController.getPlayerKilledByWerewolvesName().getPlayerName().equals(card.getPlayerName())))) && // and // looking at the person that got killed by the Witch: // if the Witch killed no one this round (this can happen) diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/model/NetworkPackage.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/model/NetworkPackage.java index af1d158..78e5fd6 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/model/NetworkPackage.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/model/NetworkPackage.java @@ -14,7 +14,6 @@ */ public class NetworkPackage implements Serializable { - public enum PACKAGE_TYPE { SERVER_HELLO, CLIENT_HELLO, START_GAME, UPDATE, VOTING_START, VOTING_RESULT, WITCH_RESULT_ELIXIR, WITCH_RESULT_POISON, PHASE, DONE, ABORT } private PACKAGE_TYPE messageType; @@ -96,8 +95,6 @@ public void setPayload(T object) throws Exception { * @return the casted object */ public T getPayload() { - return payload; - } } diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/model/Player.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/model/Player.java index ae9208c..95b829c 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/model/Player.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/model/Player.java @@ -3,6 +3,7 @@ import org.secuso.privacyfriendlywerwolf.R; import java.io.Serializable; +import java.util.Objects; /** @@ -28,7 +29,7 @@ public class Player implements Serializable { * the player's death status */ private boolean isDead = false; - private static long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; /** * Every player can act in a certain role, which are defined here @@ -39,7 +40,7 @@ public enum Role { WITCH(R.string.role_witch), SEER(R.string.role_seer); - private int roleName; + private final int roleName; Role(int roleName) { this.roleName = roleName; @@ -106,4 +107,9 @@ public long getPlayerId() { public void setPlayerId(long playerId) { this.playerId = playerId; } + + @Override + public int hashCode() { + return Objects.hash(name, playerRole, playerId, isDead); + } } diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/preferences/NumberPickerPreference.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/preferences/NumberPickerPreference.java index 0095d95..61370e4 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/preferences/NumberPickerPreference.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/preferences/NumberPickerPreference.java @@ -17,7 +17,6 @@ * @author Tobias Kowalski */ public class NumberPickerPreference extends DialogPreference { - // allowed range private int maxValue = 1200; private int minValue = 1; diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/server/ServerGameController.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/server/ServerGameController.java index 210ed79..6faed09 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/server/ServerGameController.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/server/ServerGameController.java @@ -173,18 +173,12 @@ public void startNextPhase() { gameContext.setCurrentPhase(nextPhase(phase)); if (gameContext.getCurrentPhase() == GamePhaseEnum.PHASE_DAY_START) { - // in case that two player died in the night, we want to mix up - // the order in which they are shown in the notification popup - Random rand = new Random(); - int index = rand.nextInt(2); - ContextUtil.RANDOM_INDEX = index; - try { NetworkPackage np = new NetworkPackage<>(NetworkPackage.PACKAGE_TYPE.PHASE); np.setPayload(gameContext.getCurrentPhase()); - if (gameContext.getCurrentPhase() == GamePhaseEnum.PHASE_DAY_START) { - np.setOption("random number", String.valueOf(index)); - } +// if (gameContext.getCurrentPhase() == GamePhaseEnum.PHASE_DAY_START) { +// np.setOption("random number", String.valueOf(index)); +// } Log.d(TAG, "send current phase: " + gameContext.getCurrentPhase()); serverHandler.send(np); } catch (Exception e) { diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/server/WebSocketServerHandler.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/server/WebSocketServerHandler.java index 9553aa2..a966d11 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/server/WebSocketServerHandler.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/server/WebSocketServerHandler.java @@ -52,141 +52,130 @@ public void startServer() { Log.d(TAG, "Starting the server"); server = new AsyncHttpServer(); - _sockets = new ArrayList(); + _sockets = new ArrayList<>(); //websocket refinmnent - server.websocket("/ws", new AsyncHttpServer.WebSocketRequestCallback() { - - @Override - public void onConnected(final WebSocket webSocket, AsyncHttpServerRequest request) { - //initial communication on connection of client - _sockets.add(webSocket); - Log.d(TAG, "Count of websockets:" + _sockets.size()); - //initiate request for player name + server.websocket("/ws", (webSocket, request) -> { + //initial communication on connection of client + _sockets.add(webSocket); + Log.d(TAG, "Count of websockets:" + _sockets.size()); + //initiate request for player name + + try { + final Gson gson = new GsonBuilder() + .setLenient() + .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE) + .create(); + NetworkPackage np = new NetworkPackage<>(SERVER_HELLO); + long id = Double.doubleToLongBits(Math.random()); + Player player = new Player(); + player.setPlayerId(id); + np.setPayload(player); + webSocket.send(gson.toJson(np).trim()); + } catch (Exception e) { + e.printStackTrace(); + } + //closing procedures + webSocket.setClosedCallback(ex -> { + Log.e(TAG, "Server: i'm completed, even though i shouldn't be."); try { - final Gson gson = new GsonBuilder() - .setLenient() - .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE) - .create(); - NetworkPackage np = new NetworkPackage(SERVER_HELLO); - long id = Double.doubleToLongBits(Math.random()); - Player player = new Player(); - player.setPlayerId(id); - np.setPayload(player); - webSocket.send(gson.toJson(np).trim()); - } catch (Exception e) { - e.printStackTrace(); + if (ex != null) { + ex.printStackTrace(); + Log.d("WebSocket", "Error: " + ex.getMessage()); + } + } finally { + _sockets.remove(webSocket); + } + }); + //will get called when client sends a string message! + //all communication handled over controller! + //this are callbacks after client send a String + webSocket.setStringCallback(s -> { + final Gson gson = new GsonBuilder() + .setLenient() + .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE) + .create(); + String npString; + try { + npString = URLDecoder.decode(s, "UTF-8"); + } catch (UnsupportedEncodingException e) { + npString = s; } - //closing procedures - webSocket.setClosedCallback(new CompletedCallback() { - @Override - public void onCompleted(Exception ex) { - Log.e(TAG, "Server: i'm completed, even though i shouldnt be."); - try { - if (ex != null) { - ex.printStackTrace(); - Log.d("WebSocket", "Error: " + ex.getMessage()); - } - } finally { - _sockets.remove(webSocket); - } + JsonReader networkPackageReader = new JsonReader(new StringReader(npString)); + networkPackageReader.setLenient(true); + final NetworkPackage networkPackage = gson.fromJson(networkPackageReader, NetworkPackage.class); + + // CLIENT_HELLO does not run on the GameThread + if (networkPackage.getType() == NetworkPackage.PACKAGE_TYPE.CLIENT_HELLO) { + String playerString; + try { + playerString = URLDecoder.decode(networkPackage.getPayload().toString(), "UTF-8").replaceAll(" ", ""); + ; + } catch (UnsupportedEncodingException e) { + playerString = networkPackage.getPayload().toString().replaceAll(" ", ""); + ; } - }); - //will get called when client sends a string message! - //all communication handled over controller! - //this are callbacks after client send a String - webSocket.setStringCallback(new WebSocket.StringCallback() { - @Override - public void onStringAvailable(String s) { - final Gson gson = new GsonBuilder() - .setLenient() - .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE) - .create(); - String npString; - try { - npString = URLDecoder.decode(s, "UTF-8"); - } catch (UnsupportedEncodingException e) { - npString = s; - } - JsonReader networkPackageReader = new JsonReader(new StringReader(npString)); - networkPackageReader.setLenient(true); - final NetworkPackage networkPackage = gson.fromJson(networkPackageReader, NetworkPackage.class); - - // CLIENT_HELLO does not run on the GameThread - if (networkPackage.getType() == NetworkPackage.PACKAGE_TYPE.CLIENT_HELLO) { - String playerString; - try { - playerString = URLDecoder.decode(networkPackage.getPayload().toString(), "UTF-8").replaceAll(" ", "");; - } catch (UnsupportedEncodingException e) { - playerString = networkPackage.getPayload().toString().replaceAll(" ", "");; - } - - JsonReader playerReader = new JsonReader(new StringReader(playerString)); - playerReader.setLenient(true); - Player player = gson.fromJson(playerReader, Player.class); - serverGameController.addPlayer(player); - // TODO after Release: implement SERVER ACK - } else { - // post game logic onto the GameThread - serverGameController.getGameActivity().runOnGameThread(new Runnable() { - @Override - public void run() { - - switch (networkPackage.getType()) { - case VOTING_RESULT: - Log.d(TAG, (++votingCounter) + ". Voting Request"); - String votedForName = (String) networkPackage.getPayload(); - if (!TextUtils.isEmpty(votedForName)) { - serverGameController.handleVotingResult(votedForName); - } else { - serverGameController.handleVotingResult(EMPTY_VOTING_PLAYER); - } - break; - case WITCH_RESULT_POISON: - //Log.d(TAG, "Received result by witch, which is "); - String poisonId = networkPackage.getOption(SettingsEnum.WITCH_POISON.toString()); - if (!TextUtils.isEmpty(poisonId)) { - serverGameController.handleWitchResultPoison(Long.parseLong(poisonId)); - } else { - serverGameController.handleWitchResultPoison(null); - } - break; - case WITCH_RESULT_ELIXIR: - String elixirId = networkPackage.getOption(SettingsEnum.WITCH_ELIXIR.toString()); - if (!TextUtils.isEmpty(elixirId)) { - serverGameController.handleWitchResultElixir(Long.parseLong(elixirId)); - } else { - serverGameController.handleWitchResultElixir(null); - } - break; - case DONE: - Log.d(TAG, "Another Client is done! in Phase " + serverGameController.getGameContext().getCurrentPhase() + ", count is: " + ++requestCounter); - //requestCounter++; - if (requestCounter == _sockets.size()) { - Log.d(TAG, "All " + _sockets.size() + " Players are done!"); - requestCounter = 0; - if (ServerGameController.HOST_IS_DONE) { - ServerGameController.CLIENTS_ARE_DONE = true; - Log.d(TAG, "Everyone is done!!!"); - Log.d(TAG, "in Phase " + serverGameController.getGameContext().getCurrentPhase()); - serverGameController.startNextPhase(); - } else { - Log.d(TAG, "The Clients are waiting for the Host (why you so slow ._.)"); - ServerGameController.CLIENTS_ARE_DONE = true; - } - } - break; + JsonReader playerReader = new JsonReader(new StringReader(playerString)); + playerReader.setLenient(true); + Player player = gson.fromJson(playerReader, Player.class); + serverGameController.addPlayer(player); + // TODO after Release: implement SERVER ACK + } else { + // post game logic onto the GameThread + serverGameController.getGameActivity().runOnGameThread(() -> { + + switch (networkPackage.getType()) { + case VOTING_RESULT: + Log.d(TAG, (++votingCounter) + ". Voting Request"); + String votedForName = (String) networkPackage.getPayload(); + if (!TextUtils.isEmpty(votedForName)) { + serverGameController.handleVotingResult(votedForName); + } else { + serverGameController.handleVotingResult(EMPTY_VOTING_PLAYER); + } + break; + case WITCH_RESULT_POISON: + //Log.d(TAG, "Received result by witch, which is "); + String poisonId = networkPackage.getOption(SettingsEnum.WITCH_POISON.toString()); + if (!TextUtils.isEmpty(poisonId)) { + serverGameController.handleWitchResultPoison(Long.parseLong(poisonId)); + } else { + serverGameController.handleWitchResultPoison(null); + } + break; + case WITCH_RESULT_ELIXIR: + String elixirId = networkPackage.getOption(SettingsEnum.WITCH_ELIXIR.toString()); + if (!TextUtils.isEmpty(elixirId)) { + serverGameController.handleWitchResultElixir(Long.parseLong(elixirId)); + } else { + serverGameController.handleWitchResultElixir(null); + } + break; + case DONE: + Log.d(TAG, "Another Client is done! in Phase " + serverGameController.getGameContext().getCurrentPhase() + ", count is: " + ++requestCounter); + //requestCounter++; + if (requestCounter == _sockets.size()) { + Log.d(TAG, "All " + _sockets.size() + " Players are done!"); + requestCounter = 0; + if (ServerGameController.HOST_IS_DONE) { + ServerGameController.CLIENTS_ARE_DONE = true; + Log.d(TAG, "Everyone is done!!!"); + Log.d(TAG, "in Phase " + serverGameController.getGameContext().getCurrentPhase()); + serverGameController.startNextPhase(); + } else { + Log.d(TAG, "The Clients are waiting for the Host (why you so slow ._.)"); + ServerGameController.CLIENTS_ARE_DONE = true; } } - }, 0); + break; } - } - }); - } + }, 0); + } + }); }); // listen on port 5000 diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/util/ContextUtil.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/util/ContextUtil.java index 44a7b64..afdc50a 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/util/ContextUtil.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/util/ContextUtil.java @@ -19,8 +19,6 @@ public class ContextUtil { public static boolean IS_FIRST_ROUND = true; public static boolean END_OF_ROUND = false; - public static int RANDOM_INDEX = -1; - public static boolean isDuplicateName(String playerName){ boolean result = false; GameContext context = GameContext.getInstance(); @@ -38,7 +36,5 @@ public static void destroy() { IS_FIRST_ROUND = true; END_OF_ROUND = false; - - RANDOM_INDEX = -1; } } diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/util/Screen.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/util/Screen.java index 1ad160f..48ad6ea 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/util/Screen.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/util/Screen.java @@ -25,15 +25,6 @@ /** Utilities for working with screen sizes and orientations */ public final class Screen { - - private static class Orientation { - private static final int LANDSCAPE = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; - private static final int PORTRAIT = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; - private static final int REVERSE_LANDSCAPE = 8; // ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE - private static final int REVERSE_PORTRAIT = 9; // ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT - private static final int UNSPECIFIED = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; - } - /** This class may not be instantiated */ private Screen() { } @@ -42,23 +33,15 @@ private Screen() { } * * @param activity an `Activity` reference */ - @SuppressLint("NewApi") - @SuppressWarnings("deprecation") public static void lockOrientation(final Activity activity) { final Display display = activity.getWindowManager().getDefaultDisplay(); final int rotation = display.getRotation(); final int width, height; - if (Build.VERSION.SDK_INT >= 13) { - Point size = new Point(); - display.getSize(size); - width = size.x; - height = size.y; - } - else { - width = display.getWidth(); - height = display.getHeight(); - } + Point size = new Point(); + display.getSize(size); + width = size.x; + height = size.y; switch (rotation) { case Surface.ROTATION_90: diff --git a/app/src/main/res/layout/activity_game.xml b/app/src/main/res/layout/activity_game.xml index 1f48bfd..7d3e31a 100644 --- a/app/src/main/res/layout/activity_game.xml +++ b/app/src/main/res/layout/activity_game.xml @@ -1,5 +1,5 @@ - - - - + - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_help.xml b/app/src/main/res/layout/activity_help.xml index f11c288..49ffac1 100644 --- a/app/src/main/res/layout/activity_help.xml +++ b/app/src/main/res/layout/activity_help.xml @@ -1,5 +1,5 @@ - - - - - + - + - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 1e83c22..47827b6 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,5 +1,5 @@ - - - + - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index cfc1570..ec72a12 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -1,5 +1,5 @@ - - - + - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_start_client.xml b/app/src/main/res/layout/activity_start_client.xml index 19ddcec..c2f873b 100644 --- a/app/src/main/res/layout/activity_start_client.xml +++ b/app/src/main/res/layout/activity_start_client.xml @@ -1,4 +1,4 @@ - - --> - + - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_start_host.xml b/app/src/main/res/layout/activity_start_host.xml index 7444759..ad0c515 100644 --- a/app/src/main/res/layout/activity_start_host.xml +++ b/app/src/main/res/layout/activity_start_host.xml @@ -1,4 +1,4 @@ - - - + - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_tutorial.xml b/app/src/main/res/layout/activity_tutorial.xml index 3566348..8cd5499 100644 --- a/app/src/main/res/layout/activity_tutorial.xml +++ b/app/src/main/res/layout/activity_tutorial.xml @@ -5,7 +5,7 @@ android:layout_height="match_parent" tools:context=".activity.TutorialActivity"> - diff --git a/app/src/main/res/layout/toolbar.xml b/app/src/main/res/layout/toolbar.xml index def7a29..9f8bd29 100644 --- a/app/src/main/res/layout/toolbar.xml +++ b/app/src/main/res/layout/toolbar.xml @@ -1,16 +1,16 @@ - - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index e3221c5..9384cc7 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -156,14 +156,14 @@ Danach starten die Phasen wieder von neuem. Machen Sie sich für die Abstimmung bereit! - Klicke hier um zu starten --> - Starte die nächste Nacht --> - Starte die Abstimmung --> - - Das Spiel wird in Kürze beendet... - Der Spielleiter hat das Spiel abgebrochen. Sie werden in Kürze auf das Hauptmenü geleitet... - wurde in dieser Nacht ermordet! - wurden in dieser Nacht ermordet! + Klicke hier um zu starten —> + Starte die nächste Nacht —> + Starte die Abstimmung —> + + Das Spiel wird in Kürze beendet… + Der Spielleiter hat das Spiel abgebrochen. Sie werden in Kürze auf das Hauptmenü geleitet… + %1$s (%2$s) wurde in dieser Nacht ermordet! + %1$s und %2$s (%3$s) wurden in dieser Nacht ermordet! In dieser Nacht ist NIEMAND gestorben! Vergiftet wurde: Klick auf eine Spielerkarte, um eine Identität zu erfahren! @@ -177,7 +177,7 @@ Danach starten die Phasen wieder von neuem. Wähle eine Karte! DIE BEWOHNER HABEN GEWONNEN DIE WERWÖLFE HABEN GEWONNEN - Das Ergebnis der Abstimmung... + Das Ergebnis der Abstimmung… VERLOREN GEWONNEN @@ -222,7 +222,7 @@ Danach starten die Phasen wieder von neuem. Interpret: Kevin MacLeod Lizenz: CC-BY-3.0 Quelle: Incompetech - Verbinde... + Verbinde… Bitte schalten Sie das WLAN ein und öffnen Sie die Seite neu! Namenlos diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index af06adf..4cbde33 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -84,7 +84,7 @@ What can the werewolves do? The werewolves appear as villagers during the day, but wake up as werewolves at night and kill somebody to satisfy their needs. They do not want to be uncovered and act very shy and innocent during the day. They even accuse others to be the werewolves. What can the witch do? - The witch is a mystic person which does not appear special during the day. In the night they prepare potions. The witch can poison someone in the village whom they suspect is a werewolf. Alternatively, the witch can use an elixir to save someone's life. Unfortunately the witch is already very old and thus can only prepare one poison and one elixir in a game. + The witch is a mystic person which does not appear special during the day. In the night they prepare potions. The witch can poison someone in the village whom they suspect is a werewolf. Alternatively, the witch can use an elixir to save someone\'s life. Unfortunately the witch is already very old and thus can only prepare one poison and one elixir in a game. What can the seer do? The seer has special powers. Although appearing as a ordinary villager during the day they can reveal one person\'s identity during the night. The seer is able to do this every night as long as they are alive. What is the game\'s sequence? @@ -157,8 +157,8 @@ After these phases the process starts again. Game is Over - VILLAGERS WIN Prepare to vote! The voting results.. - Click here to start the Night --> - Click here to start the Voting --> + Click here to start the Night —> + Click here to start the Voting —> Poison Elixir You poisoned Killed by Werewolves @@ -166,15 +166,15 @@ After these phases the process starts again. Click on a Player\'s Card to see his identity! NO ONE died this Night! VICTIMS - was killed this Night! - were killed this Night! + %1$s (%2$s) was killed this Night! + %1$s and %2$s (%3$s) were killed this Night! YOU WIN YOU LOSE Aborting game - The Game will end in a few seconds... + The Game will end in a few seconds… When everyone is ready, press the blue button in the bottom right corner to start the game! - The host has stopped the game. You will be directed to the Main menu shortly... - Click here to start the Game --> + The host has stopped the game. You will be directed to the Main menu shortly… + Click here to start the Game —> Choose another Player This player is already dead! You can\'t poison a dead player @@ -211,7 +211,7 @@ After these phases the process starts again. License: CC-BY-3.0 Source: Incompetech Timer - Connecting... + Connecting… Please enable Wifi and reload the page! Anonymous diff --git a/build.gradle b/build.gradle index 0971a99..f449705 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.3.2' + classpath 'com.android.tools.build:gradle:7.2.1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/gradle.properties b/gradle.properties index aac7c9b..9e6fce1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,6 +9,8 @@ # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. +android.enableJetifier=true +android.useAndroidX=true org.gradle.jvmargs=-Xmx1536m # When configured, Gradle will run in incubating parallel mode. diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 566e213..37a30e6 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,6 @@ -#Wed Mar 13 23:59:58 CET 2019 +#Wed Jul 13 13:22:10 CEST 2022 distributionBase=GRADLE_USER_HOME +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip -distributionSha256Sum=36bf7ff499223d5139f005822130ccca784c91591b514677fd376eed966c907e +zipStoreBase=GRADLE_USER_HOME From 8475a2fbdabe9941c6bb1a13b4ab8ee5a4bf0a4d Mon Sep 17 00:00:00 2001 From: JFronny Date: Wed, 13 Jul 2022 17:43:39 +0200 Subject: [PATCH 2/3] Support for hosting through Local-Only Hotspot --- app/src/main/AndroidManifest.xml | 6 +- .../activity/StartClientActivity.java | 8 + .../activity/StartHostActivity.java | 58 +++-- .../context/GameContext.java | 2 - .../helpers/PermissionHelper.java | 202 ++++++++++++------ .../main/res/layout/activity_start_host.xml | 2 +- app/src/main/res/values-de/strings.xml | 8 +- app/src/main/res/values/strings.xml | 8 +- 8 files changed, 190 insertions(+), 104 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 86236f9..e377a82 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,11 +2,15 @@ + + + + + - */ public class StartHostActivity extends BaseActivity { - /** - * views - */ - private TextView infoip; - private Toolbar toolbar; - private Button buttonStart; private ArrayList stringPlayers; private ArrayAdapter playerAdapter; @@ -63,11 +59,11 @@ protected void onCreate(Bundle savedInstanceState) { serverGameController.destroy(); setContentView(R.layout.activity_start_host); - infoip = findViewById(R.id.infoip); + TextView connection_info = findViewById(R.id.connection_info); - infoip.setText(getIpAddress()); + connection_info.setText(getConnectionInfo()); - toolbar = findViewById(R.id.toolbar); + Toolbar toolbar = findViewById(R.id.toolbar); toolbar.setSubtitle(R.string.startgame_subtitle); PermissionHelper.showWifiAlert(this); @@ -77,7 +73,7 @@ protected void onCreate(Bundle savedInstanceState) { serverGameController.startServer(); - buttonStart = findViewById(R.id.btn_start); + Button buttonStart = findViewById(R.id.btn_start); // user clicks the button to start the game @@ -154,42 +150,38 @@ public void renderUI() { } /** - * get the ip adress from the android framework + * Get the info message containing details for clients to connect to this host * * @return the IP */ - private String getIpAddress() { - if (!PermissionHelper.isWifiEnabled(this)) { + private String getConnectionInfo() { + String result = ""; + if (PermissionHelper.getHotspotSSID() != null) { + result += getResources().getString(R.string.startgame_hotspot_details, PermissionHelper.getHotspotSSID(), PermissionHelper.getHotspotPassphrase()); + } + if (PermissionHelper.getHotspotSSID() == null && !PermissionHelper.isWifiEnabled(this)) { return getResources().getString(R.string.text_view_enable_wifi); } else { - String ip = ""; try { - Enumeration enumNetworkInterfaces = NetworkInterface - .getNetworkInterfaces(); + Enumeration enumNetworkInterfaces = NetworkInterface.getNetworkInterfaces(); while (enumNetworkInterfaces.hasMoreElements()) { - NetworkInterface networkInterface = enumNetworkInterfaces - .nextElement(); - Enumeration enumInetAddress = networkInterface - .getInetAddresses(); + NetworkInterface networkInterface = enumNetworkInterfaces.nextElement(); + Enumeration enumInetAddress = networkInterface.getInetAddresses(); while (enumInetAddress.hasMoreElements()) { InetAddress inetAddress = enumInetAddress.nextElement(); if (inetAddress.isSiteLocalAddress()) { - ip += getResources().getString(R.string.startgame_use_this_ip) + " " - + inetAddress.getHostAddress(); + if (!result.isEmpty()) result += "\n"; + result += getResources().getString(R.string.startgame_use_this_ip, inetAddress.getHostAddress(), networkInterface.getDisplayName()); } - } - } - } catch (SocketException e) { e.printStackTrace(); - ip += "Something Wrong! " + e + "\n"; + result += "Something Wrong! " + e + "\n"; } - - return ip; } + return result; } /** @@ -212,4 +204,10 @@ public void onBackPressed() { intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); startActivity(intent); } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + PermissionHelper.handlePermissionRequestResult(this, requestCode, permissions, grantResults); + } } \ No newline at end of file diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/context/GameContext.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/context/GameContext.java index af5cef9..fd0d1a9 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/context/GameContext.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/context/GameContext.java @@ -63,11 +63,9 @@ public void updateSetting(SettingsEnum setting, String pref) { * @param gc the existing GameContext instance */ public void copy(GameContext gc) { - this.setPlayers(gc.getPlayersList()); this.setSettings(gc.getSettings()); this.setCurrentPhase(gc.getCurrentPhase()); - } public Player getPlayerByName(String playerName) { diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/PermissionHelper.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/PermissionHelper.java index 6ff46b5..7f609ed 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/PermissionHelper.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/PermissionHelper.java @@ -1,12 +1,21 @@ package org.secuso.privacyfriendlywerwolf.helpers; +import android.Manifest; +import android.app.Activity; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; +import android.content.pm.PackageManager; +import android.location.LocationManager; import android.net.wifi.WifiManager; -import androidx.core.app.ActivityCompat; -import androidx.core.content.ContextCompat; +import android.os.Build; +import android.os.Handler; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; import org.secuso.privacyfriendlywerwolf.R; import org.secuso.privacyfriendlywerwolf.activity.MainActivity; @@ -19,86 +28,143 @@ */ public class PermissionHelper { - private static final int PERMISSIONS_REQUEST_INTERNET = 0; + private static final String TAG = "PermissionHelper"; + private static WifiManager.LocalOnlyHotspotReservation hotspotReservation; public static boolean isWifiEnabled(final Context context) { - WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); - return wifiManager.isWifiEnabled(); + return getWifiManager(context).isWifiEnabled(); } - public static void showWifiAlert(final Context context) { + public static @Nullable String getHotspotSSID() { + if (hotspotReservation == null) return null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + return hotspotReservation.getSoftApConfiguration().getSsid(); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + return hotspotReservation.getWifiConfiguration().SSID; + } else return null; + } - WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); + public static String getHotspotPassphrase() { + if (hotspotReservation == null) return null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + return hotspotReservation.getSoftApConfiguration().getPassphrase(); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + return hotspotReservation.getWifiConfiguration().preSharedKey; + } else return null; + } - // check if we are allowed to check permissions - // TODO: what is this for? - /*if (ContextCompat.checkSelfPermission(context, - Manifest.permission.INTERNET) - != PackageManager.PERMISSION_GRANTED || !wifiManager.isWifiEnabled()) {*/ + public static void showWifiAlert(final Activity context) { + if (!getWifiManager(context).isWifiEnabled()) { + AlertDialog.Builder builder = new AlertDialog.Builder(context) + .setTitle(R.string.startgame_need_wifi) + .setIcon(R.drawable.ic_signal_wifi_off_black_24dp) + .setCancelable(false); + + // this is a button for testing with emulators. because emulators always + // return false on method isWifiEnabled, when pressing "OKAY" emulator handy + // always gets redirected to the main menu, so we have a emulator button here +// builder.setNeutralButton(R.string.emulator, (DialogInterface.OnClickListener) (dialog, which) -> { +// // just a button for testing. keeps emulator in clientActivity +// }) + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + if (hotspotReservation != null) return; + builder.setMessage(R.string.startgame_need_wifi_message_hotspot); + builder.setNegativeButton(android.R.string.no, (dialog, which) -> returnToMenu(context)); + builder.setPositiveButton(R.string.startgame_create_hotspot, (dialog, which) -> setupHotspot(context)); + } else { + builder.setMessage(R.string.startgame_need_wifi_message); + builder.setPositiveButton(R.string.button_okay, (dialog, which) -> returnToMenu(context)); + } + builder.show(); + } + } - // we show an permission request explanation if wifi is turned of or no permissions - // TODO: what is this for? - /*if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, - Manifest.permission.INTERNET) ||*/ - if(!wifiManager.isWifiEnabled()) { + private static void setupHotspot(final Activity context) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions((Activity) context, new String[] {Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_REQUEST_INTERNET); + return; + } + if (!getLocationManager(context).isProviderEnabled(LocationManager.GPS_PROVIDER)) { new AlertDialog.Builder(context) - .setTitle(R.string.startgame_need_wifi) - .setMessage(R.string.startgame_need_wifi_message) - // TODO: this brings trouble on my phone/ makes things complicated - /*.setNegativeButton(R.string.startgame_need_wifi_open_settings, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - - Intent intent = new Intent(android.provider.Settings.ACTION_WIFI_SETTINGS, null); - List activities = context.getPackageManager().queryIntentActivities(intent, 0); - - // if on the device is now wifi settings available use standard wireless settings - // if no settings at all, then just don't do anything - if(activities.size() == 0) { - intent = new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS); - activities = context.getPackageManager().queryIntentActivities(intent, 0); - - if(activities.size() != 0) { - context.startActivity(intent); - } - } - - } - })*/ - - // this is a button for testing with emulators. because emulators always - // return false on method isWifiEnabled, when pressing "OKAY" emulator handy - // always gets redirected to the main menu, so we have a emulator button here - /*.setNeutralButton(R.string.emulator, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - // just a button for testing. keeps emulator in clientActivity - } - })*/ - .setPositiveButton(R.string.button_okay, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - // go back to main menu - Intent intent = new Intent(context, MainActivity.class); - // erase backstack (pressing back-button now leads to home screen) - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); - intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); - context.startActivity(intent); - } - }) + .setTitle(R.string.startgame_create_hotspot_failed) .setIcon(R.drawable.ic_signal_wifi_off_black_24dp) .setCancelable(false) + .setMessage(R.string.startgame_create_hotspot_failed_gps_message) + .setPositiveButton(R.string.button_okay, (dialog, which) -> returnToMenu(context)) .show(); + return; } - /*} else { + getWifiManager(context).startLocalOnlyHotspot(new WifiManager.LocalOnlyHotspotCallback() { + @Override + public void onStarted(WifiManager.LocalOnlyHotspotReservation reservation) { + super.onStarted(reservation); + hotspotReservation = reservation; + showWifiAlert(context); + context.recreate(); + } + + @Override + public void onStopped() { + super.onStopped(); + hotspotReservation = null; + } + + @Override + public void onFailed(int reason) { + super.onFailed(reason); + Log.d(TAG, "Could not set up hotspot: " + reason); + new AlertDialog.Builder(context) + .setTitle(R.string.startgame_create_hotspot_failed) + .setIcon(R.drawable.ic_signal_wifi_off_black_24dp) + .setCancelable(false) + .setMessage(R.string.startgame_create_hotspot_failed_message) + .setPositiveButton(R.string.button_okay, (dialog, which) -> returnToMenu(context)) + .show(); + } + }, new Handler()); + } + } + + public static void handlePermissionRequestResult(AppCompatActivity context, int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + switch (requestCode) { + case PERMISSIONS_REQUEST_INTERNET: + if (permissions.length == 2 + && permissions[0].equals(Manifest.permission.ACCESS_COARSE_LOCATION) + && permissions[1].equals(Manifest.permission.ACCESS_FINE_LOCATION) + && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + setupHotspot(context); + } else { + Log.d(TAG, "User did not allow location access, which is required for the hotspot"); + returnToMenu(context); + } + break; + default: + Log.e(TAG, "Attempted to handle permission request result with unknown code: " + requestCode); + returnToMenu(context); + break; + } + } + + private static WifiManager getWifiManager(Context context) { + return (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE); + } + + private static LocationManager getLocationManager(Context context) { + return (LocationManager) context.getApplicationContext().getSystemService(Context.LOCATION_SERVICE); + } - // No explanation needed, we can request the permission. - // TODO: why? - ActivityCompat.requestPermissions((Activity) context, - new String[]{Manifest.permission.READ_CONTACTS}, - PERMISSIONS_REQUEST_INTERNET); - }*/ + private static void returnToMenu(Activity context) { + // go back to main menu + Intent intent = new Intent(context, MainActivity.class); + // erase backstack (pressing back-button now leads to home screen) + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); + intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); + context.startActivity(intent); } } diff --git a/app/src/main/res/layout/activity_start_host.xml b/app/src/main/res/layout/activity_start_host.xml index ad0c515..d1a48ee 100644 --- a/app/src/main/res/layout/activity_start_host.xml +++ b/app/src/main/res/layout/activity_start_host.xml @@ -39,7 +39,7 @@ android:textStyle="bold" /> diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 9384cc7..7d4ab28 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -72,7 +72,8 @@ Danach starten die Phasen wieder von neuem. Spiel starten Neues Spiel erstellen - Nutze diese IP-Adresse: + Nutze diese IP-Adresse %1$s um dich über %2$s zu verbinden + Verbinde dich mit dem Hotspot "%1$s" (Password: %2$s) Warte auf andere Spieler … Spiel beitreten @@ -83,6 +84,11 @@ Danach starten die Phasen wieder von neuem. WLAN ist notwendig Damit das Spiel eine Verbindung mit anderen Spielern aufbauen kann, ist WLAN-Zugang erforderlich. Bitte aktivieren Sie WLAN und verbinden sich mit dem Netzwerk, in dem das Spiel stattfinden soll. + Damit das Spiel eine Verbindung mit anderen Spielern aufbauen kann, ist WLAN-Zugang erforderlich. Durch das Bestätigen dieser Nachricht wird ein lokaler Hotspot erstellt, um das Spielen ohne Internetverbindung zu ermöglichen. Sie können den Vorgang stattdessen auch abbrechen und sich manuell mit einem Netzwerk verbinden. + Hotspot erstellen + Hotspot nicht erstellt + Der Hotspot konnte nicht erstellt werden. Bitte versuche es erneut oder verwende eine normale Internetverbindung! + Die Standortdienste müssen zum Erstellen des Hotspots aktiviert sein! Spielerkarte Dies ist die Karte eines anderen Spielers. Finden Sie heraus, wer Freund und wer Feind ist! diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4cbde33..1f7a870 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -25,10 +25,16 @@ Create A New Game Waiting for other players to connect … - Use this IP to connect: + Use "%1$s" to connect via %2$s + Connect to the hotspot "%1$s" with the password %2$s Start Game WiFi is mandatory In order to play the game wifi needs to be activated. Please check if it is enabled. If not please go to the settings and activate it. + In order to play the game wifi needs to be activated. Alternatively, a local-only hotspot can be created to allow playing the game offline. + Create Hotspot + Could not create Hotspot + Something went wrong while trying to create the Hotspot. Please try again or connect to a normal network instead! + You must enable the location service to create a Hotspot! You need more players To have more fun with the game you should at least be 6 players. In spite of that, do you still want to proceed to the game? From 726f3f00079a4cd5ad8876ad16bb71d07f46d308 Mon Sep 17 00:00:00 2001 From: JFronny Date: Thu, 14 Jul 2022 17:43:03 +0200 Subject: [PATCH 3/3] Additional cleanup, restore compatibility --- app/.gitignore | 1 + .../activity/StartHostActivity.java | 9 - .../client/ClientGameController.java | 4 +- .../client/WebsocketClientHandler.java | 278 ++++++++---------- .../helpers/PermissionHelper.java | 2 +- .../helpers/PlayerCardClickListener.java | 44 +-- .../server/ServerGameController.java | 17 +- .../server/WebSocketServerHandler.java | 7 - .../util/ContextUtil.java | 5 +- app/src/main/res/values-de/strings.xml | 9 +- app/src/main/res/values/strings.xml | 11 +- 11 files changed, 167 insertions(+), 220 deletions(-) diff --git a/app/.gitignore b/app/.gitignore index 796b96d..956c004 100644 --- a/app/.gitignore +++ b/app/.gitignore @@ -1 +1,2 @@ /build +/release \ No newline at end of file diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/StartHostActivity.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/StartHostActivity.java index 393b3ca..020b3ed 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/StartHostActivity.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/activity/StartHostActivity.java @@ -68,14 +68,11 @@ protected void onCreate(Bundle savedInstanceState) { PermissionHelper.showWifiAlert(this); - // start the server serverGameController.startServer(); - Button buttonStart = findViewById(R.id.btn_start); - // user clicks the button to start the game buttonStart.setOnClickListener(new View.OnClickListener() { StartHostActivity activity; @@ -102,16 +99,11 @@ public void onClick(View view) { .setCancelable(false) .show(); } - } - - }.init(this)); - ListView list = findViewById(R.id.host_player_list); - stringPlayers = new ArrayList<>(); fillStringPlayers(); @@ -146,7 +138,6 @@ private void fillStringPlayers() { public void renderUI() { fillStringPlayers(); runOnUiThread(() -> playerAdapter.notifyDataSetChanged()); - } /** diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/client/ClientGameController.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/client/ClientGameController.java index 9cc2601..4ae53ef 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/client/ClientGameController.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/client/ClientGameController.java @@ -637,13 +637,13 @@ public void initiateDayPhase() { * Gets the list of players killed in the current night */ private List getKilledPlayers() { - //TODO don't send details about the death source to the client + //TODO send deaths as a list of IDs instead of attached to their source final Player killedPlayer = GameContext.getInstance().getPlayerById(ContextUtil.lastKilledPlayerID); final Player killedByWitchPlayer = GameContext.getInstance().getPlayerById(ContextUtil.lastKilledPlayerIDByWitch); List killedPlayers = new ArrayList<>(); if (killedPlayer != null) killedPlayers.add(killedPlayer); if (killedByWitchPlayer != null) killedPlayers.add(killedByWitchPlayer); - Collections.shuffle(killedPlayers); + if (ContextUtil.RANDOM_INDEX == 1) Collections.reverse(killedPlayers); return killedPlayers; } diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/client/WebsocketClientHandler.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/client/WebsocketClientHandler.java index ec149ee..8d87cb0 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/client/WebsocketClientHandler.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/client/WebsocketClientHandler.java @@ -6,7 +6,6 @@ import com.google.gson.FieldNamingPolicy; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import com.google.gson.stream.JsonReader; import com.koushikdutta.async.http.AsyncHttpClient; import com.koushikdutta.async.http.WebSocket; @@ -17,7 +16,6 @@ import org.secuso.privacyfriendlywerwolf.model.Player; import org.secuso.privacyfriendlywerwolf.util.ContextUtil; -import java.io.StringReader; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; @@ -67,170 +65,154 @@ public void onCompleted(Exception ex, final WebSocket webSocket) { if (ex != null) { Log.e(TAG, "Connection failure. Show on UI"); - gameController.getStartClientActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - gameController.connectionFailed(); - } - }); + gameController.getStartClientActivity().runOnUiThread(() -> gameController.connectionFailed()); ex.printStackTrace(); return; } - webSocket.setStringCallback(new WebSocket.StringCallback() { - public void onStringAvailable(String s) { - // all communication handled over controller! - Log.d(TAG, "Client has received a request: " + s); - - final Gson gson = new GsonBuilder() - .setLenient() - .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE) - .create(); - - String npString; - try { - npString = URLDecoder.decode(s, "UTF-8"); - } catch (UnsupportedEncodingException e) { - npString = s; - } + webSocket.setStringCallback(s -> { + // all communication handled over controller! + Log.d(TAG, "Client has received a request: " + s); - final NetworkPackage np = gson.fromJson(npString, NetworkPackage.class); + final Gson gson = new GsonBuilder() + .setLenient() + .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE) + .create(); - // SERVER_HELLO AND START_GAME do not run on the GameThread - if (np.getType() == NetworkPackage.PACKAGE_TYPE.SERVER_HELLO) { + String npString; + try { + npString = URLDecoder.decode(s, "UTF-8"); + } catch (UnsupportedEncodingException e) { + npString = s; + } - String playerString = null; - try { - playerString = URLDecoder.decode(np.getPayload().toString(), "UTF-8"); - } catch (UnsupportedEncodingException e) { - playerString = np.getPayload().toString(); - } + final NetworkPackage np = gson.fromJson(npString, NetworkPackage.class); - Player player = gson.fromJson(playerString, Player.class); - Log.d(TAG, "Server send me my Player Object: " + np.getPayload().toString()); - gameController.setMyId(player.getPlayerId()); - //TODO after Release: only show SuccessfullConnection notification after ACK of server received - gameController.showSuccesfulConnection(); + // SERVER_HELLO AND START_GAME do not run on the GameThread + if (np.getType() == NetworkPackage.PACKAGE_TYPE.SERVER_HELLO) { - try { - NetworkPackage resp = new NetworkPackage(NetworkPackage.PACKAGE_TYPE.CLIENT_HELLO); - player.setName(playerName); - resp.setPayload(player); - webSocket.send(URLEncoder.encode(gson.toJson(resp).trim(), "UTF-8")); - } catch (Exception e) { - Log.d(TAG, e.getMessage()); - } - // TODO after Release: implement Callback for Server ACK - } else if (np.getType() == NetworkPackage.PACKAGE_TYPE.START_GAME) { - GameContext gcToStartGame = gson.fromJson(np.getPayload().toString(), GameContext.class); - gameController.startGame(gcToStartGame); - gameController.updateMe(); - } else if(np.getType() == NetworkPackage.PACKAGE_TYPE.ABORT) { - gameController.getGameActivity().showTextPopup(R.string.popup_title_abort, R.string.popup_text_abort_by_host); - gameController.getGameActivity().runOnGameThread(new Runnable() { - @Override - public void run() { - gameController.abortGame(); - } - }, 5000); - } else { - //all GameActivites will run on an own thread - gameController.getGameActivity().runOnGameThread(new Runnable() { - @Override - public void run() { + String playerString; + try { + playerString = URLDecoder.decode(np.getPayload().toString(), "UTF-8"); + } catch (UnsupportedEncodingException e) { + playerString = np.getPayload().toString(); + } - //react to the different network packages of the server - switch (np.getType()) { + Player player = gson.fromJson(playerString, Player.class); + Log.d(TAG, "Server send me my Player Object: " + np.getPayload().toString()); + gameController.setMyId(player.getPlayerId()); + //TODO after Release: only show SuccessfullConnection notification after ACK of server received + gameController.showSuccesfulConnection(); - case UPDATE: - GameContext gcToUpdate = gson.fromJson(np.getPayload().toString(), GameContext.class); - //TODO: in Start_GAME the gameController does this, no effect, but check the duplicate - GameContext.getInstance().copy(gcToUpdate); - gameController.updateMe(); + try { + NetworkPackage resp = new NetworkPackage<>(NetworkPackage.PACKAGE_TYPE.CLIENT_HELLO); + player.setName(playerName); + resp.setPayload(player); + webSocket.send(URLEncoder.encode(gson.toJson(resp).trim(), "UTF-8")); + } catch (Exception e) { + Log.d(TAG, e.getMessage()); + } + // TODO after Release: implement Callback for Server ACK + } else if (np.getType() == NetworkPackage.PACKAGE_TYPE.START_GAME) { + GameContext gcToStartGame = gson.fromJson(np.getPayload().toString(), GameContext.class); + gameController.startGame(gcToStartGame); + gameController.updateMe(); + } else if(np.getType() == NetworkPackage.PACKAGE_TYPE.ABORT) { + gameController.getGameActivity().showTextPopup(R.string.popup_title_abort, R.string.popup_text_abort_by_host); + gameController.getGameActivity().runOnGameThread(() -> gameController.abortGame(), 5000); + } else { + //all GameActivites will run on an own thread + gameController.getGameActivity().runOnGameThread(() -> { + //react to the different network packages of the server + switch (np.getType()) { + + case UPDATE: + GameContext gcToUpdate = gson.fromJson(np.getPayload().toString(), GameContext.class); + //TODO: in Start_GAME the gameController does this, no effect, but check the duplicate + GameContext.getInstance().copy(gcToUpdate); + gameController.updateMe(); + break; + case VOTING_RESULT: + String playerVotedForName = np.getOption("playerName"); + if (!TextUtils.isEmpty(playerVotedForName)) { + Log.d(TAG, playerVotedForName + " got voted"); + } else { + Log.d(TAG, "No player was voted"); + } + gameController.handleVotingResult(playerVotedForName); + break; + case WITCH_RESULT_POISON: + String poisonedPlayer = np.getOption("poisenedName"); + if (!TextUtils.isEmpty(poisonedPlayer)) { + Log.d(TAG, poisonedPlayer + " got poisened by the Witch"); + } else { + Log.d(TAG, "Witch did not use her poison elixir"); + } + gameController.handleWitchPoisonResult(poisonedPlayer); + break; + case WITCH_RESULT_ELIXIR: + String savedPlayer = np.getOption("savedName"); + if (!TextUtils.isEmpty(savedPlayer)) { + Log.d(TAG, savedPlayer + " got saved by the Witch"); + } else { + Log.d(TAG, "Witch did not use her healing elixir"); + } + gameController.handleWitchElixirResult(savedPlayer); + break; + case PHASE: + GamePhaseEnum phase = gson.fromJson(np.getPayload().toString(), GamePhaseEnum.class); + Log.d(TAG, "Current phase is " + phase); + gameController.setPhase(phase); + //react to the different phases + switch (phase) { + case PHASE_WEREWOLF_START: + Log.d(TAG, "Client: Starting WerewolfPhase"); + gameController.initiateWerewolfPhase(); + break; + case PHASE_WEREWOLF_END: + Log.d(TAG, "Client: Ending WerewolfPhase"); + gameController.endWerewolfPhase(); break; - case VOTING_RESULT: - String playerVotedForName = np.getOption("playerName"); - if (!TextUtils.isEmpty(playerVotedForName)) { - Log.d(TAG, playerVotedForName + " got voted"); - } else { - Log.d(TAG, "No player was voted"); - } - gameController.handleVotingResult(playerVotedForName); + case PHASE_WITCH_ELIXIR: + Log.d(TAG, "Client: Starting WitchElixirPhase"); + gameController.initiateWitchElixirPhase(); break; - case WITCH_RESULT_POISON: - String poisenedPlayer = np.getOption("poisenedName"); - if (!TextUtils.isEmpty(poisenedPlayer)) { - Log.d(TAG, poisenedPlayer + " got poisened by the Witch"); - } else { - Log.d(TAG, "Witch did not use her poison elixir"); - } - gameController.handleWitchPoisonResult(poisenedPlayer); + case PHASE_WITCH_POISON: + Log.d(TAG, "Client: Starting WitchPoisonPhase"); + gameController.initiateWitchPoisonPhase(); break; - case WITCH_RESULT_ELIXIR: - String savedPlayer = np.getOption("savedName"); - if (!TextUtils.isEmpty(savedPlayer)) { - Log.d(TAG, savedPlayer + " got saved by the Witch"); - } else { - Log.d(TAG, "Witch did not use her healing elixir"); - } - gameController.handleWitchElixirResult(savedPlayer); + case PHASE_SEER: + Log.d(TAG, "Client: Starting SeerPhase"); + gameController.initiateSeerPhase(); break; - case PHASE: - GamePhaseEnum phase = gson.fromJson(np.getPayload().toString(), GamePhaseEnum.class); - Log.d(TAG, "Current phase is " + phase); - gameController.setPhase(phase); - //react to the different phases - switch (phase) { - case PHASE_WEREWOLF_START: - Log.d(TAG, "Client: Starting WerewolfPhase"); - gameController.initiateWerewolfPhase(); - break; - case PHASE_WEREWOLF_END: - Log.d(TAG, "Client: Ending WerewolfPhase"); - gameController.endWerewolfPhase(); - break; - case PHASE_WITCH_ELIXIR: - Log.d(TAG, "Client: Starting WitchElixirPhase"); - gameController.initiateWitchElixirPhase(); - break; - case PHASE_WITCH_POISON: - Log.d(TAG, "Client: Starting WitchPoisonPhase"); - gameController.initiateWitchPoisonPhase(); - break; - case PHASE_SEER: - Log.d(TAG, "Client: Starting SeerPhase"); - gameController.initiateSeerPhase(); - break; - case PHASE_SEER_END: - Log.d(TAG, "Client: Ending SeerPhase"); - gameController.endSeerPhase(); - break; - case PHASE_DAY_START: - Log.d(TAG, "Client: Starting DayPhase"); -// String randomNumberString = np.getOption("random number"); -// ContextUtil.RANDOM_INDEX = Integer.parseInt(randomNumberString); - gameController.initiateDayPhase(); - break; - case PHASE_DAY_END: - Log.d(TAG, "Client: Ending DayPhase"); - gameController.endDayPhase(); - break; - case PHASE_DAY_VOTING: - Log.d(TAG, "Client: Starting DayVotingPhase"); - gameController.initiateDayVotingPhase(); - break; - case PHASE_WEREWOLF_VOTING: - Log.d(TAG, "Client: Starting WerewolfVotingPhase"); - gameController.initiateWerewolfVotingPhase(); - break; - } + case PHASE_SEER_END: + Log.d(TAG, "Client: Ending SeerPhase"); + gameController.endSeerPhase(); break; - default: + case PHASE_DAY_START: + Log.d(TAG, "Client: Starting DayPhase"); + String randomNumberString = np.getOption("random number"); + ContextUtil.RANDOM_INDEX = Integer.parseInt(randomNumberString); + gameController.initiateDayPhase(); + break; + case PHASE_DAY_END: + Log.d(TAG, "Client: Ending DayPhase"); + gameController.endDayPhase(); + break; + case PHASE_DAY_VOTING: + Log.d(TAG, "Client: Starting DayVotingPhase"); + gameController.initiateDayVotingPhase(); + break; + case PHASE_WEREWOLF_VOTING: + Log.d(TAG, "Client: Starting WerewolfVotingPhase"); + gameController.initiateWerewolfVotingPhase(); break; } - } - }, 0); - } + break; + default: + break; + } + }, 0); } }); } diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/PermissionHelper.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/PermissionHelper.java index 7f609ed..ee9877e 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/PermissionHelper.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/PermissionHelper.java @@ -45,7 +45,7 @@ public static boolean isWifiEnabled(final Context context) { } else return null; } - public static String getHotspotPassphrase() { + public static @Nullable String getHotspotPassphrase() { if (hotspotReservation == null) return null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { return hotspotReservation.getSoftApConfiguration().getPassphrase(); diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/PlayerCardClickListener.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/PlayerCardClickListener.java index d7c39f6..0dde2ae 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/PlayerCardClickListener.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/helpers/PlayerCardClickListener.java @@ -65,28 +65,20 @@ public void onClick(final View view) { // Tell the seer that the clicked has long passed (isDead), and that she should pick another person clientGameController.getGameActivity().showTextPopup(R.string.popup_title_choose_another, R.string.popup_text_choose_another); } else { // everything is fine, tell seer the identity - String message = clientGameController.getGameActivity().getResources().getString(R.string.common_identity_of) - + " " + card.getPlayerName() + " " + clientGameController.getGameActivity().getResources().getString(R.string.common_is) - + " " + view.getResources().getString(card.getPlayerRole().getRole()); + String message = clientGameController.getGameActivity().getResources().getString(R.string.common_identity_of, card.getPlayerName(), view.getResources().getString(card.getPlayerRole().getRole())); clientGameController.getGameActivity().showTextPopup(R.string.popup_title_seer_power, message); - clientGameController.getGameActivity().runOnGameThread(new Runnable() { - @Override - public void run() { - Log.d(TAG, "SeerEnd - Current Thread: " + Thread.currentThread().getName()); - clientGameController.sendDoneToServer(); - } + clientGameController.getGameActivity().runOnGameThread(() -> { + Log.d(TAG, "SeerEnd - Current Thread: " + Thread.currentThread().getName()); + clientGameController.sendDoneToServer(); }, 2000); } // the witch clicked } else if (me.getPlayerRole() == Player.Role.WITCH && GameContext.getInstance().getCurrentPhase() == GamePhaseEnum.PHASE_WITCH_POISON) { if (!card.isDead()) { - clientGameController.getGameActivity().runOnGameThread(new Runnable() { - @Override - public void run() { - // mark clicked player as poisoned - clientGameController.selectedPlayerForWitch(card); - } + clientGameController.getGameActivity().runOnGameThread(() -> { + // mark clicked player as poisoned + clientGameController.selectedPlayerForWitch(card); }, 0); } else { // cannot poison dead players @@ -101,17 +93,13 @@ else if (me.getPlayerId() == card.getPlayerId()) new AlertDialog.Builder(view.getContext()) .setTitle(R.string.gamefield_your_player_card) .setMessage(R.string.gamefield_your_player_card_message) - .setPositiveButton(R.string.button_okay, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - String message = view.getResources().getString(R.string.gamefield_player_identity); - message += view.getResources().getString(clientGameController.getMyPlayer().getPlayerRole().getRole()); - Toast.makeText(view.getRootView().getContext(), message, Toast.LENGTH_LONG).show(); - } + .setPositiveButton(R.string.button_okay, (dialog, which) -> { + String message = view.getResources().getString(R.string.gamefield_player_identity); + message += view.getResources().getString(clientGameController.getMyPlayer().getPlayerRole().getRole()); + Toast.makeText(view.getRootView().getContext(), message, Toast.LENGTH_LONG).show(); }) - .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - // do nothing - } + .setNegativeButton(android.R.string.no, (dialog, which) -> { + // do nothing }) .setIcon(R.drawable.ic_face_black_24dp) .setCancelable(false) @@ -127,10 +115,8 @@ public void onClick(DialogInterface dialog, int which) { new AlertDialog.Builder(view.getContext()) .setTitle(R.string.gamefield_player_card) .setMessage(R.string.gamefield_player_card_message) - .setPositiveButton(R.string.button_okay, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - // do nothing - } + .setPositiveButton(R.string.button_okay, (dialog, which) -> { + // do nothing }) .setIcon(R.drawable.ic_face_black_24dp) .show(); diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/server/ServerGameController.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/server/ServerGameController.java index 6faed09..281d8da 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/server/ServerGameController.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/server/ServerGameController.java @@ -83,7 +83,6 @@ public static ServerGameController getInstance() { * the game settigs, start with the first game phase */ public void initiateGame() { - List players = gameContext.getPlayersList(); int total_amount = players.size(); @@ -112,8 +111,7 @@ public void initiateGame() { // set the role for (int nr : generated) { - - // fill werewolfes as long as we still have some left over + // fill werewolves as long as we still have some left over if (werewolfs_amount > 0) { players.get(nr).setPlayerRole(Player.Role.WEREWOLF); werewolfs_amount--; @@ -152,8 +150,6 @@ else if (villagers_amount > 0) { Log.d(TAG, "Server send: start the Game!"); gameContext.setCurrentPhase(GamePhaseEnum.GAME_START); - - } @@ -173,12 +169,13 @@ public void startNextPhase() { gameContext.setCurrentPhase(nextPhase(phase)); if (gameContext.getCurrentPhase() == GamePhaseEnum.PHASE_DAY_START) { + ContextUtil.RANDOM_INDEX = new Random().nextInt(2); try { NetworkPackage np = new NetworkPackage<>(NetworkPackage.PACKAGE_TYPE.PHASE); np.setPayload(gameContext.getCurrentPhase()); -// if (gameContext.getCurrentPhase() == GamePhaseEnum.PHASE_DAY_START) { -// np.setOption("random number", String.valueOf(index)); -// } + if (gameContext.getCurrentPhase() == GamePhaseEnum.PHASE_DAY_START) { + np.setOption("random number", String.valueOf(ContextUtil.RANDOM_INDEX)); + } Log.d(TAG, "send current phase: " + gameContext.getCurrentPhase()); serverHandler.send(np); } catch (Exception e) { @@ -252,20 +249,16 @@ public void startNextPhase() { } public void startServer() { - serverHandler.startServer(); } public void addPlayer(Player player) { - - if (ContextUtil.isDuplicateName(player.getPlayerName())) { player.setName(player.getPlayerName() + "_" + duplicate_player_indicator++); } gameContext.addPlayer(player); startHostActivity.renderUI(); - } /** diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/server/WebSocketServerHandler.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/server/WebSocketServerHandler.java index a966d11..597e893 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/server/WebSocketServerHandler.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/server/WebSocketServerHandler.java @@ -7,23 +7,16 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.stream.JsonReader; -import com.koushikdutta.async.AsyncSSLSocketWrapper; -import com.koushikdutta.async.callback.CompletedCallback; import com.koushikdutta.async.http.WebSocket; import com.koushikdutta.async.http.server.AsyncHttpServer; -import com.koushikdutta.async.http.server.AsyncHttpServerRequest; import org.secuso.privacyfriendlywerwolf.enums.SettingsEnum; import org.secuso.privacyfriendlywerwolf.model.NetworkPackage; import org.secuso.privacyfriendlywerwolf.model.Player; -import java.io.BufferedInputStream; -import java.io.InputStreamReader; -import java.io.StringBufferInputStream; import java.io.StringReader; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; -import java.net.URLEncoder; import java.util.ArrayList; import java.util.List; diff --git a/app/src/main/java/org/secuso/privacyfriendlywerwolf/util/ContextUtil.java b/app/src/main/java/org/secuso/privacyfriendlywerwolf/util/ContextUtil.java index afdc50a..d5055d9 100644 --- a/app/src/main/java/org/secuso/privacyfriendlywerwolf/util/ContextUtil.java +++ b/app/src/main/java/org/secuso/privacyfriendlywerwolf/util/ContextUtil.java @@ -10,7 +10,6 @@ * @author Tobias Kowalski */ public class ContextUtil { - public static long lastKilledPlayerID = Constants.NO_PLAYER_KILLED_THIS_ROUND; public static long lastKilledPlayerIDByWitch = Constants.NO_PLAYER_KILLED_THIS_ROUND; @@ -19,6 +18,8 @@ public class ContextUtil { public static boolean IS_FIRST_ROUND = true; public static boolean END_OF_ROUND = false; + public static int RANDOM_INDEX = -1; + public static boolean isDuplicateName(String playerName){ boolean result = false; GameContext context = GameContext.getInstance(); @@ -36,5 +37,7 @@ public static void destroy() { IS_FIRST_ROUND = true; END_OF_ROUND = false; + + RANDOM_INDEX = -1; } } diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 7d4ab28..fd73c22 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -171,7 +171,7 @@ Danach starten die Phasen wieder von neuem. %1$s (%2$s) wurde in dieser Nacht ermordet! %1$s und %2$s (%3$s) wurden in dieser Nacht ermordet! In dieser Nacht ist NIEMAND gestorben! - Vergiftet wurde: + Vergiftet wurde: %1$s Klick auf eine Spielerkarte, um eine Identität zu erfahren! Sobald alle bereit sind, klicke auf den blauen Button in der rechten unteren Ecke! Das Spiel wird beendet @@ -192,13 +192,12 @@ Danach starten die Phasen wieder von neuem. Beginnt die Diskussion Das Spiel schließt in 15 Sekunden - Die Identität von - ist + Die Identität von %1$s ist %2$s \" Niemand .\" Dieser Spieler ist bereits gestorben! - Ihre Rolle war - Seine Rolle war + Ihre Rolle war %1$s + Seine Rolle war %1$s Wähle einen anderen Spieler Wähle einen anderen Spieler zum Vergiften! Dieser Spieler ist gestorben diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1f7a870..7d749cb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -166,7 +166,7 @@ After these phases the process starts again. Click here to start the Night —> Click here to start the Voting —> Poison Elixir - You poisoned + You poisoned %1$s Killed by Werewolves Seer Click on a Player\'s Card to see his identity! @@ -186,12 +186,11 @@ After these phases the process starts again. You can\'t poison a dead player Choose another player to poison! You are dead - Your Role was + Your Role was %1$s This player is dead - His Role was - The identity of - is - Nobody . + His Role was %1$s + The identity of %1$s is %2$s + Nobody. okay Game information You are about the start the game with following settings: