MultiplayerManager.java 5.26 KB
Newer Older
Melledy's avatar
Melledy committed
1
2
3
4
5
6
7
8
9
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;
10
import emu.grasscutter.net.proto.PlayerApplyEnterMpResultNotifyOuterClass;
Melledy's avatar
Melledy committed
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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) {
28
		GenshinPlayer target = getServer().getPlayerByUid(targetUid);
Melledy's avatar
Melledy committed
29
		if (target == null) {
30
			player.sendPacket(new PacketPlayerApplyEnterMpResultNotify(targetUid, "", false, PlayerApplyEnterMpResultNotifyOuterClass.PlayerApplyEnterMpResultNotify.Reason.PLAYER_CANNOT_ENTER_MP));
Melledy's avatar
Melledy committed
31
32
33
34
35
36
37
38
			return;
		}
		
		// Sanity checks - Dont let player join if already in multiplayer
		if (player.getWorld().isMultiplayer()) {
			return;
		}
		
39
		/*
Melledy's avatar
Melledy committed
40
41
42
43
		if (target.getWorld().isDungeon()) {
			player.sendPacket(new PacketPlayerApplyEnterMpResultNotify(targetUid, "", false, PlayerApplyEnterMpReason.SceneCannotEnter));
			return;
		}
44
		*/
Melledy's avatar
Melledy committed
45
46
		
		// Get request
47
		CoopRequest request = target.getCoopRequests().get(player.getUid());
Melledy's avatar
Melledy committed
48
49
50
51
52
53
54
55
		
		if (request != null && !request.isExpired()) {
			// Join request already exists
			return;
		}
		
		// Put request in
		request = new CoopRequest(player);
56
		target.getCoopRequests().put(player.getUid(), request);
Melledy's avatar
Melledy committed
57
58
59
60
61
		
		// Packet
		target.sendPacket(new PacketPlayerApplyEnterMpNotify(player));
	}

62
	public void applyEnterMpReply(GenshinPlayer hostPlayer, int applyUid, boolean isAgreed) {
Melledy's avatar
Melledy committed
63
		// Checks
64
		CoopRequest request = hostPlayer.getCoopRequests().get(applyUid);
Melledy's avatar
Melledy committed
65
66
67
68
69
70
		if (request == null || request.isExpired()) {
			return;
		}
		
		// Remove now that we are handling it
		GenshinPlayer requester = request.getRequester();
71
		hostPlayer.getCoopRequests().remove(applyUid);
Melledy's avatar
Melledy committed
72
		
73
		// Sanity checks - Dont let the requesting player join if they are already in multiplayer
Melledy's avatar
Melledy committed
74
		if (requester.getWorld().isMultiplayer()) {
75
			request.getRequester().sendPacket(new PacketPlayerApplyEnterMpResultNotify(hostPlayer, false, PlayerApplyEnterMpResultNotifyOuterClass.PlayerApplyEnterMpResultNotify.Reason.PLAYER_CANNOT_ENTER_MP));
Melledy's avatar
Melledy committed
76
77
78
79
			return;
		}
		
		// Response packet
80
		request.getRequester().sendPacket(new PacketPlayerApplyEnterMpResultNotify(hostPlayer, isAgreed, PlayerApplyEnterMpResultNotifyOuterClass.PlayerApplyEnterMpResultNotify.Reason.PLAYER_JUDGE));
Melledy's avatar
Melledy committed
81
82
83
84
85
86
87
		
		// Declined
		if (!isAgreed) {
			return;
		}

		// Success
88
		if (!hostPlayer.getWorld().isMultiplayer()) {
Melledy's avatar
Melledy committed
89
			// Player not in multiplayer, create multiplayer world
90
			World world = new World(hostPlayer, true);
Melledy's avatar
Melledy committed
91
92

			// Add
93
			world.addPlayer(hostPlayer);
Melledy's avatar
Melledy committed
94
95
			
			// Rejoin packet
96
			hostPlayer.sendPacket(new PacketPlayerEnterSceneNotify(hostPlayer, hostPlayer, EnterType.ENTER_SELF, EnterReason.HostFromSingleToMp, hostPlayer.getScene().getId(), hostPlayer.getPos()));
Melledy's avatar
Melledy committed
97
98
		}
		
99
100
101
102
		// Set scene pos and id of requester to the host player's
		requester.getPos().set(hostPlayer.getPos());
		requester.getRotation().set(hostPlayer.getRotation());
		requester.setSceneId(hostPlayer.getSceneId());
Melledy's avatar
Melledy committed
103
		
104
105
106
		// Make requester join
		hostPlayer.getWorld().addPlayer(requester);

Melledy's avatar
Melledy committed
107
		// Packet
108
		requester.sendPacket(new PacketPlayerEnterSceneNotify(requester, hostPlayer, EnterType.ENTER_OTHER, EnterReason.TeamJoin, hostPlayer.getScene().getId(), hostPlayer.getPos()));
Melledy's avatar
Melledy committed
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
	}
	
	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
129
		player.sendPacket(new PacketPlayerEnterSceneNotify(player, EnterType.ENTER_SELF, EnterReason.TeamBack, player.getScene().getId(), player.getPos()));
Melledy's avatar
Melledy committed
130
131
132
133
134
135
136
137
138
139
140
		
		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
141
		GenshinPlayer victim = player.getServer().getPlayerByUid(targetUid);
Melledy's avatar
Melledy committed
142
143
144
145
146
147
148
149
150
151
152
153
154
155
		
		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);
		
156
		victim.sendPacket(new PacketPlayerEnterSceneNotify(victim, EnterType.ENTER_SELF, EnterReason.TeamKick, victim.getScene().getId(), victim.getPos()));
Melledy's avatar
Melledy committed
157
158
159
		return true;
	}
}