summaryrefslogtreecommitdiff
path: root/server/src/main/java/kz/ilotterytea/frogartha/server/ServerHandlers.java
blob: 9add4ce136eaa35e9e2bb0c4603d4c0785ab9abb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package kz.ilotterytea.frogartha.server;

import com.badlogic.gdx.math.Vector3;
import kz.ilotterytea.frogartha.FrogarthaConstants;
import kz.ilotterytea.frogartha.domain.Identity;
import kz.ilotterytea.frogartha.domain.PlayerState;
import kz.ilotterytea.frogartha.domain.actions.ChangedDirectionAction;
import kz.ilotterytea.frogartha.domain.actions.JoinRoomAction;
import kz.ilotterytea.frogartha.domain.actions.LeaveRoomAction;
import kz.ilotterytea.frogartha.domain.actions.PlayerJumpAction;
import kz.ilotterytea.frogartha.domain.events.ChangedDirectionEvent;
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 java.util.Optional;

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) {
        if (server.getPlayers()
            .stream()
            .filter((x) -> x.getIdentity() != null)
            .anyMatch((x) -> x.getIdentity().equals(identity) && 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) {
        if (player.getRoom() == null) {
            throw PlayerKickException.notInRoom();
        }

        PlayerState state = player.getState();

        float nowTimestamp = System.currentTimeMillis() / 1000f;

        if (state.getNextJumpTimestamp() > nowTimestamp) {
            throw PlayerKickException.jumpSpam();
        }

        state.setNextJumpTimestamp(nowTimestamp + action.getJumpStrength());

        // calculating start and end positions
        Vector3 position = state.getPosition();
        Vector3 startPosition = position.cpy();

        float jumpDistance = action.getJumpStrength() * FrogarthaConstants.Player.JUMP_SPEED;
        Vector3 d = new Vector3(state.getDirection()).sub(startPosition).nor();

        Vector3 endPosition = new Vector3(
            position.x + d.x * jumpDistance,
            position.y,
            position.z + d.z * jumpDistance
        );

        state.setPosition(endPosition.x, endPosition.y, endPosition.z);

        PlayerJumpEvent event = new PlayerJumpEvent(
            player.getId(), startPosition, endPosition, action.getJumpStrength()
        );
        log.log("{} jumped from {} to {} with strength {}", player, startPosition, endPosition, action.getJumpStrength());

        Room room = player.getRoom();
        room.broadcast(event);
    }

    public static void handleChangedDirectionAction(PlayerConnection player, ChangedDirectionAction action) {
        if (player.getRoom() == null) {
            throw PlayerKickException.notInRoom();
        }

        PlayerState state = player.getState();
        Vector3 direction = action.getDirection();

        state.setDirection(direction.x, state.getPosition().y, direction.z);

        ChangedDirectionEvent event = new ChangedDirectionEvent(player.getId(), state.getDirection());

        Room room = player.getRoom();
        room.broadcast(event);
    }

    public static void handleJoinRoomAction(PlayerConnection player, JoinRoomAction action) {
        Optional<Room> optionalRoom = server.getRooms().stream()
            .filter((x) ->
                x.getPlayers().size() < FrogarthaConstants.Room.MAX_PLAYERS &&
                    x.getTopic().equals(action.getTopic())
            )
            .findFirst();

        Room room = optionalRoom.orElse(new Room(action.getTopic()));
        room.addPlayer(player);

        if (optionalRoom.isEmpty()) {
            server.getRooms().add(room);
        }

        log.log("{} joined {}", player, room);
    }

    public static void handleLeaveRoomAction(PlayerConnection player, LeaveRoomAction action) {
        Optional<Room> optionalRoom = server.getRooms().stream()
            .filter((x) -> x.getPlayers().contains(player))
            .findFirst();

        if (optionalRoom.isEmpty()) {
            throw PlayerKickException.illegalOperation();
        }

        Room room = optionalRoom.get();
        room.removePlayer(player);

        if (room.getPlayers().isEmpty()) {
            server.getRooms().remove(room);
        }

        log.log("{} left {}", player, room);
    }
}