Commit 49a4adcb authored by Ulrik Røsby's avatar Ulrik Røsby
Browse files

Merge branch 'i4/implementMultiplayerService' into 'master'

I4/implement multiplayer service

See merge request !18
parents 63836a0c c95b0995
Pipeline #173303 failed with stages
in 7 minutes and 47 seconds
apply plugin: 'com.google.gms.google-services'
android {
buildToolsVersion "32.0.0"
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
compileSdkVersion 32
sourceSets {
main {
......@@ -18,7 +26,7 @@ android {
}
defaultConfig {
applicationId "se.battlegoo.battlegoose"
minSdkVersion 21
minSdkVersion 26
targetSdkVersion 32
versionCode 1
versionName "1.0"
......@@ -97,4 +105,11 @@ task run(type: Exec) {
commandLine "$adb", 'shell', 'am', 'start', '-n', 'se.battlegoo.battlegoose/se.battlegoo.battlegoose.AndroidLauncher'
}
dependencies {
implementation platform('com.google.firebase:firebase-bom:29.3.0')
implementation 'com.google.firebase:firebase-analytics-ktx'
implementation 'com.google.firebase:firebase-auth-ktx'
implementation 'com.google.firebase:firebase-database-ktx'
}
eclipse.project.name = appName + "-android"
{
"project_info": {
"project_number": "637382925655",
"firebase_url": "https://battlegoose-a31a7-default-rtdb.europe-west1.firebasedatabase.app",
"project_id": "battlegoose-a31a7",
"storage_bucket": "battlegoose-a31a7.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:637382925655:android:99282bfa5d00c2ab94b212",
"android_client_info": {
"package_name": "com.progark.battlegoose"
}
},
"oauth_client": [
{
"client_id": "637382925655-vjnth6kbdcv84po88oks63j1fje6br4q.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyC5wcwlZtHh2M8XLaCxu7Mc9zOdT9cin70"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "637382925655-vjnth6kbdcv84po88oks63j1fje6br4q.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:637382925655:android:8ccb793f2127b3eb94b212",
"android_client_info": {
"package_name": "se.battlegoo.battlegoose"
}
},
"oauth_client": [
{
"client_id": "637382925655-vjnth6kbdcv84po88oks63j1fje6br4q.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyC5wcwlZtHh2M8XLaCxu7Mc9zOdT9cin70"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "637382925655-vjnth6kbdcv84po88oks63j1fje6br4q.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
],
"configuration_version": "1"
}
\ No newline at end of file
buildscript {
ext.kotlinVersion = '1.3.41'
ext.kotlinVersion = '1.6.10'
repositories {
mavenLocal()
......@@ -11,7 +11,7 @@ buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:3.5.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
classpath 'com.google.gms:google-services:4.3.3'
}
}
......@@ -42,6 +42,7 @@ allprojects {
ashleyVersion = '1.7.3'
aiVersion = '1.8.2'
gdxControllersVersion = '2.1.0'
gdxFireappVersion = '3.3.0'
}
repositories {
......@@ -88,6 +89,7 @@ project(":android") {
natives "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-x86_64"
api "com.badlogicgames.gdx-controllers:gdx-controllers-android:$gdxControllersVersion"
api "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
implementation "pl.mk5.gdx-fireapp:gdx-fireapp-android:$gdxFireappVersion"
}
}
......@@ -99,7 +101,7 @@ project(":core") {
api "com.badlogicgames.gdx:gdx-box2d:$gdxVersion"
api "com.badlogicgames.gdx-controllers:gdx-controllers-core:$gdxControllersVersion"
api "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
implementation "pl.mk5.gdx-fireapp:gdx-fireapp-core:$gdxFireappVersion"
testImplementation 'junit:junit:4.13.2'
}
......
package se.battlegoo.battlegoose
data class Lobby(
val hostID: String,
val otherPlayerID: String = "",
val shouldStart: Boolean = false
)
package se.battlegoo.battlegoose.network
enum class DataPaths {
LOBBIES, RANDOM_OPPONENT_QUEUE
}
package se.battlegoo.battlegoose.network
import pl.mk5.gdx.fireapp.GdxFIRAuth
import pl.mk5.gdx.fireapp.GdxFIRDatabase
import pl.mk5.gdx.fireapp.auth.GdxFirebaseUser
import pl.mk5.gdx.fireapp.promises.Promise
import se.battlegoo.battlegoose.Lobby
import java.util.function.Consumer
class DatabaseHandler {
fun signInAnonymously(): Promise<GdxFirebaseUser> {
return GdxFIRAuth.inst().signInAnonymously()
}
fun getUserID(consumer: Consumer<String>) {
this.signInAnonymously().then<GdxFirebaseUser> { user ->
consumer.accept(user.userInfo.uid)
}
}
inline fun <reified T : Any> readPrimitiveValue(databasePath: String, consumer: Consumer<T?>) {
GdxFIRDatabase.inst()
.inReference(databasePath)
.readValue(T::class.java).then<T> {
consumer.accept(it)
}
}
inline fun <reified T : Any> readReferenceValue(databasePath: String, consumer: Consumer<T?>) {
when (T::class) {
Lobby::class -> readPrimitiveValue<HashMap<String, Any>>(
databasePath,
Consumer { data ->
if (data == null) {
consumer.accept(null)
return@Consumer
}
consumer.accept(convertToLobby(data) as T)
}
)
}
}
fun setValue(databasePath: String, value: Any): Promise<Void> {
return GdxFIRDatabase.inst().inReference(databasePath).setValue(value)
}
fun pushValue(databasePath: String, value: Any): Promise<Void> {
return GdxFIRDatabase.inst().inReference(databasePath).push().setValue(value)
}
fun convertToLobby(data: HashMap<String, Any>): Lobby {
val hostID = data["hostID"].toString()
val otherPlayerID = data["otherPlayerID"].toString()
val shouldStart = data["shouldStart"].toString().toBoolean()
return Lobby(hostID, otherPlayerID, shouldStart)
}
}
package se.battlegoo.battlegoose.network
enum class LobbyStatus {
READY, FULL, DOES_NOT_EXIST
}
package se.battlegoo.battlegoose.network
import pl.mk5.gdx.fireapp.promises.Promise
import se.battlegoo.battlegoose.Lobby
import java.util.LinkedList
import java.util.function.Consumer
import kotlin.collections.ArrayList
object MultiplayerService {
private val databaseHandler = DatabaseHandler()
init {
databaseHandler.signInAnonymously()
}
private fun userCanJoinLobby(userID: String, lobby: Lobby): Boolean {
return lobby.otherPlayerID.isNotEmpty() && lobby.otherPlayerID != userID
}
private fun joinLobby(lobbyID: String, userID: String): Promise<Void> {
return databaseHandler.setValue("${DataPaths.LOBBIES}/$lobbyID/otherPlayerID", userID)
}
fun tryCreateLobby(listener: Consumer<Lobby>) {
databaseHandler.getUserID { userID ->
databaseHandler.pushValue(DataPaths.LOBBIES.toString(), Lobby(userID)).then<Void> {
listener.accept(Lobby(userID))
}
}
}
fun tryRequestOpponent(listener: Consumer<Boolean>) {
databaseHandler.getUserID { userID ->
databaseHandler.readPrimitiveValue<Any>(
DataPaths.RANDOM_OPPONENT_QUEUE.toString()
) { data ->
val queue: LinkedList<String> = if (data !is ArrayList<*>) {
LinkedList()
} else {
LinkedList(data.map { it.toString() })
}
if (!queue.contains(userID)) {
queue.add(userID)
databaseHandler.setValue(DataPaths.RANDOM_OPPONENT_QUEUE.toString(), queue)
}
if (queue.peek() == userID && queue.size > 1) {
// TODO: This user is now responsible for creating a lobby
}
}
}
}
fun tryJoinLobby(lobbyID: String, listener: Consumer<Pair<LobbyStatus, Lobby?>>) {
databaseHandler.readReferenceValue<Lobby>(
"${DataPaths.LOBBIES}/$lobbyID",
Consumer { lobby ->
if (lobby == null) {
listener.accept(Pair(LobbyStatus.DOES_NOT_EXIST, null))
return@Consumer
}
databaseHandler.getUserID { userID ->
if (userCanJoinLobby(userID, lobby)) {
listener.accept(Pair(LobbyStatus.FULL, null))
return@getUserID
}
joinLobby(lobbyID, userID).then<Void> {
listener.accept(
Pair(
LobbyStatus.READY, Lobby(lobby.hostID, userID, lobby.shouldStart)
)
)
}
}
}
)
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment