summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorilotterytea <iltsu@alright.party>2025-01-23 20:31:23 +0500
committerilotterytea <iltsu@alright.party>2025-01-23 20:31:23 +0500
commitff9d8f584616cc3d9d7000e95f681707fd508497 (patch)
treeb56f83b921f887424e69fffde8c34753a4e09baa
parentc94a51d6ab4863e2fa6fd230def08aac3f2bf73a (diff)
feat: server-side sign-in implementation
-rw-r--r--core/src/main/java/kz/ilotterytea/frogartha/sessions/SessionClient.java16
-rw-r--r--core/src/main/java/kz/ilotterytea/frogartha/sessions/SessionHandlers.java6
-rw-r--r--gradle.properties1
-rw-r--r--server/build.gradle1
-rw-r--r--server/src/main/java/kz/ilotterytea/frogartha/server/FrogarthaServer.java5
-rw-r--r--server/src/main/java/kz/ilotterytea/frogartha/server/PlayerConnection.java11
-rw-r--r--server/src/main/java/kz/ilotterytea/frogartha/server/ServerHandlers.java51
-rw-r--r--shared/src/main/java/kz/ilotterytea/frogartha/FrogarthaConstants.java1
-rw-r--r--shared/src/main/java/kz/ilotterytea/frogartha/domain/Identity.java16
-rw-r--r--shared/src/main/java/kz/ilotterytea/frogartha/domain/actions/IdentificationAction.java48
-rw-r--r--shared/src/main/java/kz/ilotterytea/frogartha/domain/events/IdentifiedEvent.java16
-rw-r--r--shared/src/main/java/kz/ilotterytea/frogartha/exceptions/PlayerKickException.java4
-rw-r--r--shared/src/main/java/kz/ilotterytea/frogartha/utils/SerializerUtils.java2
13 files changed, 152 insertions, 26 deletions
diff --git a/core/src/main/java/kz/ilotterytea/frogartha/sessions/SessionClient.java b/core/src/main/java/kz/ilotterytea/frogartha/sessions/SessionClient.java
index a696121..681b377 100644
--- a/core/src/main/java/kz/ilotterytea/frogartha/sessions/SessionClient.java
+++ b/core/src/main/java/kz/ilotterytea/frogartha/sessions/SessionClient.java
@@ -10,6 +10,7 @@ import kz.ilotterytea.frogartha.FrogarthaGame;
import kz.ilotterytea.frogartha.domain.Identity;
import kz.ilotterytea.frogartha.domain.PlayerData;
import kz.ilotterytea.frogartha.domain.RoomTopic;
+import kz.ilotterytea.frogartha.domain.actions.IdentificationAction;
import kz.ilotterytea.frogartha.domain.actions.JoinRoomAction;
import kz.ilotterytea.frogartha.domain.actions.LeaveRoomAction;
import kz.ilotterytea.frogartha.domain.events.*;
@@ -29,6 +30,7 @@ public class SessionClient implements WebSocketListener {
private boolean isJoining, joined;
private Integer connectionId;
+ private Identity identity;
private RoomTopic topic;
private Throwable lastThrow;
@@ -75,7 +77,10 @@ public class SessionClient implements WebSocketListener {
}
if (obj instanceof IdentifiedEvent) {
- SessionHandlers.handleIdentifiedEvent((IdentifiedEvent) obj);
+ IdentifiedEvent x = (IdentifiedEvent) obj;
+ identity = x.getIdentity();
+ connectionId = x.getPlayerId();
+ log.log("The server identified me! I'm {} with ID {}", identity, connectionId);
} else if (obj instanceof PlayerJumpEvent) {
SessionHandlers.handlePlayerJumpEvent((PlayerJumpEvent) obj);
} else if (obj instanceof ChangedDirectionEvent) {
@@ -145,7 +150,10 @@ public class SessionClient implements WebSocketListener {
}
public void updateIdentity() {
- send(new Identity(game.getIdentityClient().getUsername()));
+ send(new IdentificationAction(
+ game.getIdentityClient().getClientToken(),
+ game.getIdentityClient().getAccessToken()
+ ));
}
public int getConnectionId() {
@@ -156,6 +164,10 @@ public class SessionClient implements WebSocketListener {
this.connectionId = connectionId;
}
+ public Identity getIdentity() {
+ return identity;
+ }
+
public Throwable getLastThrow() {
Throwable cpy = lastThrow;
this.lastThrow = null;
diff --git a/core/src/main/java/kz/ilotterytea/frogartha/sessions/SessionHandlers.java b/core/src/main/java/kz/ilotterytea/frogartha/sessions/SessionHandlers.java
index 9ced32b..0c89b04 100644
--- a/core/src/main/java/kz/ilotterytea/frogartha/sessions/SessionHandlers.java
+++ b/core/src/main/java/kz/ilotterytea/frogartha/sessions/SessionHandlers.java
@@ -16,12 +16,6 @@ public class SessionHandlers {
private static final FrogarthaGame game = FrogarthaGame.getInstance();
private static final SessionClient client = game.getSessionClient();
- public static void handleIdentifiedEvent(IdentifiedEvent event) {
- log.log("The server identified me!");
-
- client.setConnectionId(event.getPlayerId());
- }
-
public static void handlePlayerJumpEvent(PlayerJumpEvent event) {
if (!game.getScreen().getClass().equals(GameScreen.class)) {
log.log("The screen is not GameScreen, but the session received PlayerJumpEvent");
diff --git a/gradle.properties b/gradle.properties
index ac7c536..4b258d2 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -9,4 +9,5 @@ enableGraalNative=false
gdxVersion=1.13.1
gdxWsVersion=1.10.1.12.0
javaWebsocketVersion=1.6.0
+okhttpVersion=4.12.0
projectVersion=1.0.0
diff --git a/server/build.gradle b/server/build.gradle
index d4acfbd..9ef7670 100644
--- a/server/build.gradle
+++ b/server/build.gradle
@@ -13,6 +13,7 @@ eclipse.project.name = appName + '-server'
dependencies {
api "org.java-websocket:Java-WebSocket:$javaWebsocketVersion"
+ implementation "com.squareup.okhttp3:okhttp:$okhttpVersion"
implementation project(':shared')
}
diff --git a/server/src/main/java/kz/ilotterytea/frogartha/server/FrogarthaServer.java b/server/src/main/java/kz/ilotterytea/frogartha/server/FrogarthaServer.java
index 6e8fbde..095fb05 100644
--- a/server/src/main/java/kz/ilotterytea/frogartha/server/FrogarthaServer.java
+++ b/server/src/main/java/kz/ilotterytea/frogartha/server/FrogarthaServer.java
@@ -2,7 +2,6 @@ package kz.ilotterytea.frogartha.server;
import com.github.czyzby.websocket.serialization.SerializationException;
import com.github.czyzby.websocket.serialization.impl.ManualSerializer;
-import kz.ilotterytea.frogartha.domain.Identity;
import kz.ilotterytea.frogartha.domain.actions.*;
import kz.ilotterytea.frogartha.exceptions.PlayerKickException;
import kz.ilotterytea.frogartha.utils.Logger;
@@ -88,8 +87,8 @@ public class FrogarthaServer extends WebSocketServer {
throw PlayerKickException.internalServerError();
}
- if (obj instanceof Identity) {
- ServerHandlers.handleIdentity(player, (Identity) obj);
+ if (obj instanceof IdentificationAction) {
+ ServerHandlers.handleIdentification(player, (IdentificationAction) obj);
} else if (obj instanceof PlayerJumpAction) {
ServerHandlers.handlePlayerJumpAction(player, (PlayerJumpAction) obj);
} else if (obj instanceof ChangedDirectionAction) {
diff --git a/server/src/main/java/kz/ilotterytea/frogartha/server/PlayerConnection.java b/server/src/main/java/kz/ilotterytea/frogartha/server/PlayerConnection.java
index f1d0a3b..83f10ec 100644
--- a/server/src/main/java/kz/ilotterytea/frogartha/server/PlayerConnection.java
+++ b/server/src/main/java/kz/ilotterytea/frogartha/server/PlayerConnection.java
@@ -1,6 +1,7 @@
package kz.ilotterytea.frogartha.server;
import kz.ilotterytea.frogartha.domain.PlayerData;
+import kz.ilotterytea.frogartha.domain.actions.IdentificationAction;
import org.java_websocket.WebSocket;
import java.sql.Timestamp;
@@ -10,6 +11,7 @@ public class PlayerConnection extends PlayerData {
private final WebSocket connection;
private Room room;
+ private IdentificationAction identification;
private final Timestamp connectedTimestamp;
@@ -19,6 +21,7 @@ public class PlayerConnection extends PlayerData {
TOTAL_CONNECTION_IDS++;
this.room = null;
+ this.identification = null;
this.connectedTimestamp = new Timestamp(System.currentTimeMillis());
}
@@ -43,6 +46,14 @@ public class PlayerConnection extends PlayerData {
this.room = room;
}
+ public IdentificationAction getIdentification() {
+ return identification;
+ }
+
+ public void setIdentification(IdentificationAction identification) {
+ this.identification = identification;
+ }
+
public Timestamp getConnectedTimestamp() {
return connectedTimestamp;
}
diff --git a/server/src/main/java/kz/ilotterytea/frogartha/server/ServerHandlers.java b/server/src/main/java/kz/ilotterytea/frogartha/server/ServerHandlers.java
index 6891fef..ab5cfd4 100644
--- a/server/src/main/java/kz/ilotterytea/frogartha/server/ServerHandlers.java
+++ b/server/src/main/java/kz/ilotterytea/frogartha/server/ServerHandlers.java
@@ -2,6 +2,9 @@ package kz.ilotterytea.frogartha.server;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
+import com.badlogic.gdx.utils.JsonReader;
+import com.badlogic.gdx.utils.JsonValue;
+import com.badlogic.gdx.utils.JsonWriter;
import kz.ilotterytea.frogartha.FrogarthaConstants;
import kz.ilotterytea.frogartha.domain.Identity;
import kz.ilotterytea.frogartha.domain.PlayerState;
@@ -12,6 +15,7 @@ import kz.ilotterytea.frogartha.domain.events.IdentifiedEvent;
import kz.ilotterytea.frogartha.domain.events.PlayerJumpEvent;
import kz.ilotterytea.frogartha.exceptions.PlayerKickException;
import kz.ilotterytea.frogartha.utils.Logger;
+import okhttp3.*;
import java.util.Optional;
@@ -19,18 +23,51 @@ public class ServerHandlers {
private static final Logger log = new Logger(ServerHandlers.class);
private static final FrogarthaServer server = FrogarthaServer.getInstance();
- public static void handleIdentity(PlayerConnection player, Identity identity) {
+ public static void handleIdentification(PlayerConnection player, IdentificationAction action) {
+ JsonValue json = new JsonValue(JsonValue.ValueType.object);
+ json.addChild("clientToken", new JsonValue(action.getClientToken()));
+ json.addChild("accessToken", new JsonValue(action.getAccessToken()));
+
+ OkHttpClient client = new OkHttpClient();
+
+ Request httpRequest = new Request.Builder()
+ .post(RequestBody.create(json.toJson(JsonWriter.OutputType.json), MediaType.parse("application/json; charset=utf-8")))
+ .url(FrogarthaConstants.URLS.IDENTITY_IDENTIFY_URL)
+ .build();
+
+ try (Response response = client.newCall(httpRequest).execute()) {
+ if (response.body() == null) {
+ throw new Exception("Response body is null");
+ }
+
+ json = new JsonReader().parse(response.body().string());
+
+ if (response.code() != 200) {
+ throw new Exception(json.get("error").getString("message"));
+ }
+
+ Identity identity = new Identity(
+ json.get("data").getLong("id"),
+ json.get("data").getString("username")
+ );
+
+ player.setIdentification(action);
+ player.setIdentity(identity);
+ player.send(new IdentifiedEvent(player.getId(), identity));
+
+ log.log("Successfully identified {} for {}", identity, player);
+ } catch (Exception e) {
+ log.error("Failed to identify: {}", e);
+ server.kickConnection(player, PlayerKickException.badLogin(e.getMessage()));
+ return;
+ }
+
if (server.getPlayers()
.stream()
.filter((x) -> x.getIdentity() != null)
- .anyMatch((x) -> x.getIdentity().equals(identity) && x.getId() != player.getId())) {
+ .anyMatch((x) -> x.getIdentity().getId() == player.getIdentity().getId() && x.getId() != player.getId())) {
server.kickConnection(player, PlayerKickException.loggedIn());
- return;
}
-
- player.setIdentity(identity);
- player.send(new IdentifiedEvent(player.getId()));
- log.log("Successfully identified {} for {}", identity, player);
}
public static void handlePlayerJumpAction(PlayerConnection player, PlayerJumpAction action) {
diff --git a/shared/src/main/java/kz/ilotterytea/frogartha/FrogarthaConstants.java b/shared/src/main/java/kz/ilotterytea/frogartha/FrogarthaConstants.java
index 1e55d52..81c843f 100644
--- a/shared/src/main/java/kz/ilotterytea/frogartha/FrogarthaConstants.java
+++ b/shared/src/main/java/kz/ilotterytea/frogartha/FrogarthaConstants.java
@@ -13,6 +13,7 @@ public class FrogarthaConstants {
public static final String IDENTITY_VALIDATE_URL = IDENTITY_BASE_URL + "/validate";
public static final String IDENTITY_REFRESH_URL = IDENTITY_BASE_URL + "/refresh";
public static final String IDENTITY_AUTHENTICATION_URL = IDENTITY_BASE_URL + "/authenticate";
+ public static final String IDENTITY_IDENTIFY_URL = IDENTITY_BASE_URL + "/identify";
public static final String IDENTITY_REGISTRATION_URL = IDENTITY_BASE_URL;
}
diff --git a/shared/src/main/java/kz/ilotterytea/frogartha/domain/Identity.java b/shared/src/main/java/kz/ilotterytea/frogartha/domain/Identity.java
index 03c0ef4..2d81055 100644
--- a/shared/src/main/java/kz/ilotterytea/frogartha/domain/Identity.java
+++ b/shared/src/main/java/kz/ilotterytea/frogartha/domain/Identity.java
@@ -7,14 +7,20 @@ import com.github.czyzby.websocket.serialization.impl.Serializer;
public class Identity implements Transferable<Identity> {
private String username;
+ private long id;
public Identity() {
}
- public Identity(String username) {
+ public Identity(long id, String username) {
+ this.id = id;
this.username = username;
}
+ public long getId() {
+ return id;
+ }
+
public String getUsername() {
return username;
}
@@ -22,7 +28,8 @@ public class Identity implements Transferable<Identity> {
@Override
public boolean equals(Object obj) {
if (obj instanceof Identity) {
- return ((Identity) obj).username.equals(username);
+ Identity i = (Identity) obj;
+ return i.username.equals(username) && i.id == id;
}
return false;
}
@@ -31,16 +38,17 @@ public class Identity implements Transferable<Identity> {
public String toString() {
return "Identity{" +
"username='" + username + '\'' +
+ ", id=" + id +
'}';
}
@Override
public void serialize(Serializer serializer) throws SerializationException {
- serializer.serializeString(username);
+ serializer.serializeLong(id).serializeString(username);
}
@Override
public Identity deserialize(Deserializer deserializer) throws SerializationException {
- return new Identity(deserializer.deserializeString());
+ return new Identity(deserializer.deserializeLong(), deserializer.deserializeString());
}
}
diff --git a/shared/src/main/java/kz/ilotterytea/frogartha/domain/actions/IdentificationAction.java b/shared/src/main/java/kz/ilotterytea/frogartha/domain/actions/IdentificationAction.java
new file mode 100644
index 0000000..6d3c4d8
--- /dev/null
+++ b/shared/src/main/java/kz/ilotterytea/frogartha/domain/actions/IdentificationAction.java
@@ -0,0 +1,48 @@
+package kz.ilotterytea.frogartha.domain.actions;
+
+import com.github.czyzby.websocket.serialization.SerializationException;
+import com.github.czyzby.websocket.serialization.Transferable;
+import com.github.czyzby.websocket.serialization.impl.Deserializer;
+import com.github.czyzby.websocket.serialization.impl.Serializer;
+
+public class IdentificationAction implements Transferable<IdentificationAction> {
+ private String clientToken, accessToken;
+
+ public IdentificationAction() {
+ }
+
+ public IdentificationAction(String clientToken, String accessToken) {
+ this.clientToken = clientToken;
+ this.accessToken = accessToken;
+ }
+
+ public String getClientToken() {
+ return clientToken;
+ }
+
+ public String getAccessToken() {
+ return accessToken;
+ }
+
+ @Override
+ public void serialize(Serializer serializer) throws SerializationException {
+ serializer.serializeString(clientToken).serializeString(accessToken);
+ }
+
+ @Override
+ public IdentificationAction deserialize(Deserializer deserializer) throws SerializationException {
+ return new IdentificationAction(deserializer.deserializeString(), deserializer.deserializeString());
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) return false;
+
+ if (obj instanceof IdentificationAction) {
+ IdentificationAction x = (IdentificationAction) obj;
+ return x.accessToken.equals(accessToken) && x.clientToken.equals(clientToken);
+ }
+
+ return false;
+ }
+}
diff --git a/shared/src/main/java/kz/ilotterytea/frogartha/domain/events/IdentifiedEvent.java b/shared/src/main/java/kz/ilotterytea/frogartha/domain/events/IdentifiedEvent.java
index d2d9e1e..01a12fe 100644
--- a/shared/src/main/java/kz/ilotterytea/frogartha/domain/events/IdentifiedEvent.java
+++ b/shared/src/main/java/kz/ilotterytea/frogartha/domain/events/IdentifiedEvent.java
@@ -4,22 +4,30 @@ import com.github.czyzby.websocket.serialization.SerializationException;
import com.github.czyzby.websocket.serialization.Transferable;
import com.github.czyzby.websocket.serialization.impl.Deserializer;
import com.github.czyzby.websocket.serialization.impl.Serializer;
+import kz.ilotterytea.frogartha.domain.Identity;
public class IdentifiedEvent extends Event implements Transferable<IdentifiedEvent> {
+ private Identity identity;
+
public IdentifiedEvent() {
}
- public IdentifiedEvent(int playerId) {
- this.playerId = playerId;
+ public IdentifiedEvent(int playerId, Identity identity) {
+ super(playerId);
+ this.identity = identity;
+ }
+
+ public Identity getIdentity() {
+ return identity;
}
@Override
public void serialize(Serializer serializer) throws SerializationException {
- serializer.serializeInt(playerId);
+ serializer.serializeInt(playerId).serializeTransferable(identity);
}
@Override
public IdentifiedEvent deserialize(Deserializer deserializer) throws SerializationException {
- return new IdentifiedEvent(deserializer.deserializeInt());
+ return new IdentifiedEvent(deserializer.deserializeInt(), deserializer.deserializeTransferable(new Identity()));
}
}
diff --git a/shared/src/main/java/kz/ilotterytea/frogartha/exceptions/PlayerKickException.java b/shared/src/main/java/kz/ilotterytea/frogartha/exceptions/PlayerKickException.java
index e24c633..22f45cc 100644
--- a/shared/src/main/java/kz/ilotterytea/frogartha/exceptions/PlayerKickException.java
+++ b/shared/src/main/java/kz/ilotterytea/frogartha/exceptions/PlayerKickException.java
@@ -37,6 +37,10 @@ public class PlayerKickException extends RuntimeException implements Transferabl
return new PlayerKickException("Kicked for spamming");
}
+ public static PlayerKickException badLogin(String reason) {
+ return new PlayerKickException("Bad login" + ((reason != null) ? (" (" + reason + ")") : ""));
+ }
+
@Override
public void serialize(Serializer serializer) throws SerializationException {
serializer.serializeString(getMessage());
diff --git a/shared/src/main/java/kz/ilotterytea/frogartha/utils/SerializerUtils.java b/shared/src/main/java/kz/ilotterytea/frogartha/utils/SerializerUtils.java
index 3529968..2a22bcc 100644
--- a/shared/src/main/java/kz/ilotterytea/frogartha/utils/SerializerUtils.java
+++ b/shared/src/main/java/kz/ilotterytea/frogartha/utils/SerializerUtils.java
@@ -14,7 +14,9 @@ public class SerializerUtils {
serializer.register(new PlayerJumpEvent());
serializer.register(new ChangedDirectionAction());
serializer.register(new ChangedDirectionEvent());
+
serializer.register(new IdentifiedEvent());
+ serializer.register(new IdentificationAction());
serializer.register(new JoinRoomAction());
serializer.register(new PlayerJoinedRoomEvent());