Grasscutter/src/main/java/emu/grasscutter/game/managers/MultiplayerManager.java

156 lines
4.8 KiB
Java

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;
}
/*
if (target.getWorld().isDungeon()) {
player.sendPacket(new PacketPlayerApplyEnterMpResultNotify(targetUid, "", false, PlayerApplyEnterMpReason.SceneCannotEnter));
return;
}
*/
// 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
player.sendPacket(new PacketPlayerEnterSceneNotify(player, player, EnterType.EnterSelf, EnterReason.HostFromSingleToMp, player.getScene().getId(), player.getPos()));
}
// Make requester join
player.getWorld().addPlayer(requester);
// Packet
requester.sendPacket(new PacketPlayerEnterSceneNotify(requester, player, EnterType.EnterOther, EnterReason.TeamJoin, player.getScene().getId(), player.getPos()));
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
player.sendPacket(new PacketPlayerEnterSceneNotify(player, EnterType.EnterSelf, EnterReason.TeamBack, player.getScene().getId(), player.getPos()));
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);
victim.sendPacket(new PacketPlayerEnterSceneNotify(victim, EnterType.EnterSelf, EnterReason.TeamKick, victim.getScene().getId(), victim.getPos()));
return true;
}
}