MultiplayerManager.java 4.81 KB
Newer Older
Melledy's avatar
Melledy committed
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
package emu.grasscutter.game.managers;

import emu.grasscutter.game.CoopRequest;
import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.game.GenshinPlayer.SceneLoadState;
import emu.grasscutter.game.props.EnterReason;
import emu.grasscutter.net.proto.EnterTypeOuterClass.EnterType;
import emu.grasscutter.net.proto.PlayerApplyEnterMpReasonOuterClass.PlayerApplyEnterMpReason;
import emu.grasscutter.game.World;
import emu.grasscutter.server.game.GameServer;
import emu.grasscutter.server.packet.send.PacketPlayerApplyEnterMpNotify;
import emu.grasscutter.server.packet.send.PacketPlayerApplyEnterMpResultNotify;
import emu.grasscutter.server.packet.send.PacketPlayerEnterSceneNotify;

public class MultiplayerManager {
	private final GameServer server;
	
	public MultiplayerManager(GameServer server) {
		this.server = server;
	}

	public GameServer getServer() {
		return server;
	}

	public void applyEnterMp(GenshinPlayer player, int targetUid) {
		GenshinPlayer target = getServer().getPlayerById(targetUid);
		if (target == null) {
			player.sendPacket(new PacketPlayerApplyEnterMpResultNotify(targetUid, "", false, PlayerApplyEnterMpReason.PlayerCannotEnterMp));
			return;
		}
		
		// Sanity checks - Dont let player join if already in multiplayer
		if (player.getWorld().isMultiplayer()) {
			return;
		}
		
38
		/*
Melledy's avatar
Melledy committed
39
40
41
42
		if (target.getWorld().isDungeon()) {
			player.sendPacket(new PacketPlayerApplyEnterMpResultNotify(targetUid, "", false, PlayerApplyEnterMpReason.SceneCannotEnter));
			return;
		}
43
		*/
Melledy's avatar
Melledy committed
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
		
		// Get request
		CoopRequest request = target.getCoopRequests().get(player.getId());
		
		if (request != null && !request.isExpired()) {
			// Join request already exists
			return;
		}
		
		// Put request in
		request = new CoopRequest(player);
		target.getCoopRequests().put(player.getId(), request);
		
		// Packet
		target.sendPacket(new PacketPlayerApplyEnterMpNotify(player));
	}

	public void applyEnterMpReply(GenshinPlayer player, int applyUid, boolean isAgreed) {
		// Checks
		CoopRequest request = player.getCoopRequests().get(applyUid);
		if (request == null || request.isExpired()) {
			return;
		}
		
		// Remove now that we are handling it
		GenshinPlayer requester = request.getRequester();
		player.getCoopRequests().remove(applyUid);
		
		// Sanity checks - Dont let player join if already in multiplayer
		if (requester.getWorld().isMultiplayer()) {
			request.getRequester().sendPacket(new PacketPlayerApplyEnterMpResultNotify(player, false, PlayerApplyEnterMpReason.PlayerCannotEnterMp));
			return;
		}
		
		// Response packet
		request.getRequester().sendPacket(new PacketPlayerApplyEnterMpResultNotify(player, isAgreed, PlayerApplyEnterMpReason.PlayerJudge));
		
		// Declined
		if (!isAgreed) {
			return;
		}

		// Success
		if (!player.getWorld().isMultiplayer()) {
			// Player not in multiplayer, create multiplayer world
			World world = new World(player, true);

			// Add
			world.addPlayer(player);
			
			// Rejoin packet
95
			player.sendPacket(new PacketPlayerEnterSceneNotify(player, player, EnterType.EnterSelf, EnterReason.HostFromSingleToMp, player.getScene().getId(), player.getPos()));
Melledy's avatar
Melledy committed
96
97
98
99
100
101
		}
		
		// Make requester join
		player.getWorld().addPlayer(requester);
		
		// Packet
102
		requester.sendPacket(new PacketPlayerEnterSceneNotify(requester, player, EnterType.EnterOther, EnterReason.TeamJoin, player.getScene().getId(), player.getPos()));
Melledy's avatar
Melledy committed
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
		requester.getPos().set(player.getPos());
		requester.getRotation().set(player.getRotation());
	}
	
	public boolean leaveCoop(GenshinPlayer player) {
		// Make sure player's world is multiplayer
		if (!player.getWorld().isMultiplayer()) {
			return false;
		}
		
		// Make sure everyone's scene is loaded
		for (GenshinPlayer p : player.getWorld().getPlayers()) {
			if (p.getSceneLoadState() != SceneLoadState.LOADED) {
				return false;
			}
		}
		
		// Create new world for player
		World world = new World(player);
		world.addPlayer(player);
	
		// Packet
125
		player.sendPacket(new PacketPlayerEnterSceneNotify(player, EnterType.EnterSelf, EnterReason.TeamBack, player.getScene().getId(), player.getPos()));
Melledy's avatar
Melledy committed
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
		
		return true;
	}

	public boolean kickPlayer(GenshinPlayer player, int targetUid) {
		// Make sure player's world is multiplayer and that player is owner
		if (!player.getWorld().isMultiplayer() || player.getWorld().getHost() != player) {
			return false;
		}
		
		// Get victim and sanity checks
		GenshinPlayer victim = player.getServer().getPlayerById(targetUid);
		
		if (victim == null || victim == player) {
			return false;
		}
		
		// Make sure victim's scene has loaded
		if (victim.getSceneLoadState() != SceneLoadState.LOADED) {
			return false;
		}
		
		// Kick
		World world = new World(victim);
		world.addPlayer(victim);
		
152
		victim.sendPacket(new PacketPlayerEnterSceneNotify(victim, EnterType.EnterSelf, EnterReason.TeamKick, victim.getScene().getId(), victim.getPos()));
Melledy's avatar
Melledy committed
153
154
155
		return true;
	}
}