2022-04-17 12:43:07 +00:00
|
|
|
package emu.grasscutter.game.managers;
|
|
|
|
|
|
|
|
import emu.grasscutter.game.CoopRequest;
|
|
|
|
import emu.grasscutter.game.props.EnterReason;
|
2022-04-27 04:24:25 +00:00
|
|
|
import emu.grasscutter.game.world.World;
|
2022-04-17 12:43:07 +00:00
|
|
|
import emu.grasscutter.net.proto.EnterTypeOuterClass.EnterType;
|
|
|
|
import emu.grasscutter.net.proto.PlayerApplyEnterMpReasonOuterClass.PlayerApplyEnterMpReason;
|
2022-04-27 04:24:25 +00:00
|
|
|
import emu.grasscutter.game.player.Player;
|
|
|
|
import emu.grasscutter.game.player.Player.SceneLoadState;
|
2022-04-26 21:44:30 +00:00
|
|
|
import emu.grasscutter.net.proto.PlayerApplyEnterMpResultNotifyOuterClass;
|
2022-04-17 12:43:07 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-04-27 04:21:57 +00:00
|
|
|
public void applyEnterMp(Player player, int targetUid) {
|
|
|
|
Player target = getServer().getPlayerByUid(targetUid);
|
2022-04-17 12:43:07 +00:00
|
|
|
if (target == null) {
|
2022-04-26 21:44:30 +00:00
|
|
|
player.sendPacket(new PacketPlayerApplyEnterMpResultNotify(targetUid, "", false, PlayerApplyEnterMpResultNotifyOuterClass.PlayerApplyEnterMpResultNotify.Reason.PLAYER_CANNOT_ENTER_MP));
|
2022-04-17 12:43:07 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sanity checks - Dont let player join if already in multiplayer
|
|
|
|
if (player.getWorld().isMultiplayer()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-04-18 16:39:29 +00:00
|
|
|
/*
|
2022-04-17 12:43:07 +00:00
|
|
|
if (target.getWorld().isDungeon()) {
|
|
|
|
player.sendPacket(new PacketPlayerApplyEnterMpResultNotify(targetUid, "", false, PlayerApplyEnterMpReason.SceneCannotEnter));
|
|
|
|
return;
|
|
|
|
}
|
2022-04-18 16:39:29 +00:00
|
|
|
*/
|
2022-04-17 12:43:07 +00:00
|
|
|
|
|
|
|
// Get request
|
2022-04-19 09:22:21 +00:00
|
|
|
CoopRequest request = target.getCoopRequests().get(player.getUid());
|
2022-04-17 12:43:07 +00:00
|
|
|
|
|
|
|
if (request != null && !request.isExpired()) {
|
|
|
|
// Join request already exists
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Put request in
|
|
|
|
request = new CoopRequest(player);
|
2022-04-19 09:22:21 +00:00
|
|
|
target.getCoopRequests().put(player.getUid(), request);
|
2022-04-17 12:43:07 +00:00
|
|
|
|
|
|
|
// Packet
|
|
|
|
target.sendPacket(new PacketPlayerApplyEnterMpNotify(player));
|
|
|
|
}
|
|
|
|
|
2022-04-27 04:21:57 +00:00
|
|
|
public void applyEnterMpReply(Player hostPlayer, int applyUid, boolean isAgreed) {
|
2022-04-17 12:43:07 +00:00
|
|
|
// Checks
|
2022-04-19 06:09:48 +00:00
|
|
|
CoopRequest request = hostPlayer.getCoopRequests().get(applyUid);
|
2022-04-17 12:43:07 +00:00
|
|
|
if (request == null || request.isExpired()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove now that we are handling it
|
2022-04-27 04:21:57 +00:00
|
|
|
Player requester = request.getRequester();
|
2022-04-19 06:09:48 +00:00
|
|
|
hostPlayer.getCoopRequests().remove(applyUid);
|
2022-04-17 12:43:07 +00:00
|
|
|
|
2022-04-19 06:09:48 +00:00
|
|
|
// Sanity checks - Dont let the requesting player join if they are already in multiplayer
|
2022-04-17 12:43:07 +00:00
|
|
|
if (requester.getWorld().isMultiplayer()) {
|
2022-04-26 21:44:30 +00:00
|
|
|
request.getRequester().sendPacket(new PacketPlayerApplyEnterMpResultNotify(hostPlayer, false, PlayerApplyEnterMpResultNotifyOuterClass.PlayerApplyEnterMpResultNotify.Reason.PLAYER_CANNOT_ENTER_MP));
|
2022-04-17 12:43:07 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Response packet
|
2022-04-26 21:44:30 +00:00
|
|
|
request.getRequester().sendPacket(new PacketPlayerApplyEnterMpResultNotify(hostPlayer, isAgreed, PlayerApplyEnterMpResultNotifyOuterClass.PlayerApplyEnterMpResultNotify.Reason.PLAYER_JUDGE));
|
2022-04-17 12:43:07 +00:00
|
|
|
|
|
|
|
// Declined
|
|
|
|
if (!isAgreed) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Success
|
2022-04-19 06:09:48 +00:00
|
|
|
if (!hostPlayer.getWorld().isMultiplayer()) {
|
2022-04-17 12:43:07 +00:00
|
|
|
// Player not in multiplayer, create multiplayer world
|
2022-04-19 06:09:48 +00:00
|
|
|
World world = new World(hostPlayer, true);
|
2022-04-17 12:43:07 +00:00
|
|
|
|
|
|
|
// Add
|
2022-04-19 06:09:48 +00:00
|
|
|
world.addPlayer(hostPlayer);
|
2022-04-17 12:43:07 +00:00
|
|
|
|
|
|
|
// Rejoin packet
|
2022-04-26 21:44:30 +00:00
|
|
|
hostPlayer.sendPacket(new PacketPlayerEnterSceneNotify(hostPlayer, hostPlayer, EnterType.ENTER_SELF, EnterReason.HostFromSingleToMp, hostPlayer.getScene().getId(), hostPlayer.getPos()));
|
2022-04-17 12:43:07 +00:00
|
|
|
}
|
|
|
|
|
2022-04-19 06:09:48 +00:00
|
|
|
// 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());
|
2022-04-17 12:43:07 +00:00
|
|
|
|
2022-04-19 08:43:38 +00:00
|
|
|
// Make requester join
|
|
|
|
hostPlayer.getWorld().addPlayer(requester);
|
|
|
|
|
2022-04-17 12:43:07 +00:00
|
|
|
// Packet
|
2022-04-26 21:44:30 +00:00
|
|
|
requester.sendPacket(new PacketPlayerEnterSceneNotify(requester, hostPlayer, EnterType.ENTER_OTHER, EnterReason.TeamJoin, hostPlayer.getScene().getId(), hostPlayer.getPos()));
|
2022-04-17 12:43:07 +00:00
|
|
|
}
|
|
|
|
|
2022-04-27 04:21:57 +00:00
|
|
|
public boolean leaveCoop(Player player) {
|
2022-04-17 12:43:07 +00:00
|
|
|
// Make sure player's world is multiplayer
|
|
|
|
if (!player.getWorld().isMultiplayer()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make sure everyone's scene is loaded
|
2022-04-27 04:21:57 +00:00
|
|
|
for (Player p : player.getWorld().getPlayers()) {
|
2022-04-17 12:43:07 +00:00
|
|
|
if (p.getSceneLoadState() != SceneLoadState.LOADED) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create new world for player
|
|
|
|
World world = new World(player);
|
|
|
|
world.addPlayer(player);
|
|
|
|
|
|
|
|
// Packet
|
2022-04-26 21:44:30 +00:00
|
|
|
player.sendPacket(new PacketPlayerEnterSceneNotify(player, EnterType.ENTER_SELF, EnterReason.TeamBack, player.getScene().getId(), player.getPos()));
|
2022-04-17 12:43:07 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-04-27 04:21:57 +00:00
|
|
|
public boolean kickPlayer(Player player, int targetUid) {
|
2022-04-17 12:43:07 +00:00
|
|
|
// 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
|
2022-04-27 04:21:57 +00:00
|
|
|
Player victim = player.getServer().getPlayerByUid(targetUid);
|
2022-04-17 12:43:07 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2022-04-26 21:44:30 +00:00
|
|
|
victim.sendPacket(new PacketPlayerEnterSceneNotify(victim, EnterType.ENTER_SELF, EnterReason.TeamKick, victim.getScene().getId(), victim.getPos()));
|
2022-04-17 12:43:07 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|