mirror of
https://github.com/Melledy/Grasscutter.git
synced 2024-12-04 09:50:08 +00:00
154 lines
4.8 KiB
Java
154 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.getWorld().getSceneId(), player.getPos()));
|
||
|
}
|
||
|
|
||
|
// Make requester join
|
||
|
player.getWorld().addPlayer(requester);
|
||
|
|
||
|
// Packet
|
||
|
requester.sendPacket(new PacketPlayerEnterSceneNotify(requester, player, EnterType.EnterOther, EnterReason.TeamJoin, player.getWorld().getSceneId(), 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.getWorld().getSceneId(), 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.getWorld().getSceneId(), victim.getPos()));
|
||
|
return true;
|
||
|
}
|
||
|
}
|