Move PlayerTeleportEvent occurrences into World

This commit is contained in:
KingRainbow44 2022-08-01 21:25:29 -04:00
parent 1de402bd6f
commit 89575f587e
7 changed files with 78 additions and 94 deletions

View File

@ -3,8 +3,7 @@ package emu.grasscutter.command.commands;
import emu.grasscutter.command.Command; import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler; import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.server.event.player.PlayerTeleportEvent; import emu.grasscutter.server.event.player.PlayerTeleportEvent.TeleportType;
import emu.grasscutter.utils.Position;
import java.util.List; import java.util.List;
@ -24,13 +23,7 @@ public final class TeleportAllCommand implements CommandHandler {
if (player.equals(targetPlayer)) if (player.equals(targetPlayer))
continue; continue;
Position pos = targetPlayer.getPosition(); player.getWorld().transferPlayerToScene(player, targetPlayer.getSceneId(), TeleportType.COMMAND, targetPlayer.getPosition());
PlayerTeleportEvent event = new PlayerTeleportEvent(targetPlayer, PlayerTeleportEvent.TeleportType.COMMAND,
targetPlayer.getPosition(), pos);
event.call();
if(!event.isCanceled())
player.getWorld().transferPlayerToScene(player, targetPlayer.getSceneId(), event.getDestination());
} }
CommandHandler.sendMessage(sender, translate(sender, "commands.teleportAll.success")); CommandHandler.sendMessage(sender, translate(sender, "commands.teleportAll.success"));

View File

@ -3,7 +3,7 @@ package emu.grasscutter.command.commands;
import emu.grasscutter.command.Command; import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler; import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.server.event.player.PlayerTeleportEvent; import emu.grasscutter.server.event.player.PlayerTeleportEvent.TeleportType;
import emu.grasscutter.utils.Position; import emu.grasscutter.utils.Position;
import java.util.List; import java.util.List;
@ -41,29 +41,21 @@ public final class TeleportCommand implements CommandHandler {
} // Fallthrough } // Fallthrough
case 3: case 3:
try { try {
x = parseRelative(args.get(0), x); x = this.parseRelative(args.get(0), x);
y = parseRelative(args.get(1), y); y = this.parseRelative(args.get(1), y);
z = parseRelative(args.get(2), z); z = this.parseRelative(args.get(2), z);
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
CommandHandler.sendMessage(sender, translate(sender, "commands.teleport.invalid_position")); CommandHandler.sendMessage(sender, translate(sender, "commands.teleport.invalid_position"));
} }
break; break;
default: default:
sendUsageMessage(sender); this.sendUsageMessage(sender);
return; return;
} }
Position target_pos = new Position(x, y, z); Position target_pos = new Position(x, y, z);
PlayerTeleportEvent event = new PlayerTeleportEvent(targetPlayer, PlayerTeleportEvent.TeleportType.COMMAND, boolean result = targetPlayer.getWorld().transferPlayerToScene(targetPlayer, sceneId, TeleportType.COMMAND, target_pos);
targetPlayer.getPosition(), target_pos);
event.call();
// Return if event was cancelled.
if(event.isCanceled()) {
return;
}
boolean result = targetPlayer.getWorld().transferPlayerToScene(targetPlayer, sceneId, event.getDestination());
if (!result) { if (!result) {
CommandHandler.sendMessage(sender, translate(sender, "commands.teleport.exists_error")); CommandHandler.sendMessage(sender, translate(sender, "commands.teleport.exists_error"));
} else { } else {

View File

@ -5,12 +5,11 @@ import emu.grasscutter.game.player.Player;
import emu.grasscutter.net.proto.MapMarkPointTypeOuterClass.MapMarkPointType; import emu.grasscutter.net.proto.MapMarkPointTypeOuterClass.MapMarkPointType;
import emu.grasscutter.net.proto.MarkMapReqOuterClass.MarkMapReq; import emu.grasscutter.net.proto.MarkMapReqOuterClass.MarkMapReq;
import emu.grasscutter.net.proto.MarkMapReqOuterClass.MarkMapReq.Operation; import emu.grasscutter.net.proto.MarkMapReqOuterClass.MarkMapReq.Operation;
import emu.grasscutter.server.event.player.PlayerTeleportEvent; import emu.grasscutter.server.event.player.PlayerTeleportEvent.TeleportType;
import emu.grasscutter.server.packet.send.PacketMarkMapRsp; import emu.grasscutter.server.packet.send.PacketMarkMapRsp;
import emu.grasscutter.server.packet.send.PacketSceneEntityAppearNotify; import emu.grasscutter.server.packet.send.PacketSceneEntityAppearNotify;
import emu.grasscutter.utils.Position; import emu.grasscutter.utils.Position;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class MapMarksManager extends BasePlayerManager { public class MapMarksManager extends BasePlayerManager {
@ -21,7 +20,7 @@ public class MapMarksManager extends BasePlayerManager {
} }
public Map<String, MapMark> getMapMarks() { public Map<String, MapMark> getMapMarks() {
return getPlayer().getMapMarks(); return this.getPlayer().getMapMarks();
} }
public void handleMapMarkReq(MarkMapReq req) { public void handleMapMarkReq(MarkMapReq req) {
@ -31,26 +30,26 @@ public class MapMarksManager extends BasePlayerManager {
MapMark createMark = new MapMark(req.getMark()); MapMark createMark = new MapMark(req.getMark());
// keep teleporting functionality on fishhook mark. // keep teleporting functionality on fishhook mark.
if (createMark.getMapMarkPointType() == MapMarkPointType.MAP_MARK_POINT_TYPE_FISH_POOL) { if (createMark.getMapMarkPointType() == MapMarkPointType.MAP_MARK_POINT_TYPE_FISH_POOL) {
teleport(player, createMark); this.teleport(player, createMark);
return; return;
} }
addMapMark(createMark); this.addMapMark(createMark);
} }
case OPERATION_MOD -> { case OPERATION_MOD -> {
MapMark oldMark = new MapMark(req.getOld()); MapMark oldMark = new MapMark(req.getOld());
removeMapMark(oldMark.getPosition()); this.removeMapMark(oldMark.getPosition());
MapMark newMark = new MapMark(req.getMark()); MapMark newMark = new MapMark(req.getMark());
addMapMark(newMark); this.addMapMark(newMark);
} }
case OPERATION_DEL -> { case OPERATION_DEL -> {
MapMark deleteMark = new MapMark(req.getMark()); MapMark deleteMark = new MapMark(req.getMark());
removeMapMark(deleteMark.getPosition()); this.removeMapMark(deleteMark.getPosition());
} }
} }
if (op != Operation.OPERATION_GET) { if (op != Operation.OPERATION_GET) {
save(); this.save();
} }
player.getSession().send(new PacketMarkMapRsp(getMapMarks())); player.getSession().send(new PacketMarkMapRsp(this.getMapMarks()));
} }
public String getMapMarkKey(Position position) { public String getMapMarkKey(Position position) {
@ -58,12 +57,12 @@ public class MapMarksManager extends BasePlayerManager {
} }
public void removeMapMark(Position position) { public void removeMapMark(Position position) {
getMapMarks().remove(getMapMarkKey(position)); this.getMapMarks().remove(this.getMapMarkKey(position));
} }
public void addMapMark(MapMark mapMark) { public void addMapMark(MapMark mapMark) {
if (getMapMarks().size() < mapMarkMaxCount) { if (this.getMapMarks().size() < mapMarkMaxCount) {
getMapMarks().put(getMapMarkKey(mapMark.getPosition()), mapMark); this.getMapMarks().put(this.getMapMarkKey(mapMark.getPosition()), mapMark);
} }
} }
@ -75,14 +74,7 @@ public class MapMarksManager extends BasePlayerManager {
} }
Position pos = mapMark.getPosition(); Position pos = mapMark.getPosition();
PlayerTeleportEvent event = new PlayerTeleportEvent(player, PlayerTeleportEvent.TeleportType.MAP, player.getWorld().transferPlayerToScene(player, mapMark.getSceneId(), TeleportType.MAP, new Position(pos.getX(), y, pos.getZ()));
player.getPosition(), new Position(pos.getX(), y, pos.getZ())); player.getScene().broadcastPacket(new PacketSceneEntityAppearNotify(player));
event.call(); if(event.isCanceled()) return;
player.getPosition().set(event.getDestination());
if (mapMark.getSceneId() != player.getSceneId()) {
player.getWorld().transferPlayerToScene(player, mapMark.getSceneId(), player.getPosition());
} player.getScene().broadcastPacket(new PacketSceneEntityAppearNotify(player));
} }
} }

View File

@ -17,6 +17,8 @@ import emu.grasscutter.data.excels.SceneData;
import emu.grasscutter.net.packet.BasePacket; import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.proto.EnterTypeOuterClass.EnterType; import emu.grasscutter.net.proto.EnterTypeOuterClass.EnterType;
import emu.grasscutter.scripts.data.SceneConfig; import emu.grasscutter.scripts.data.SceneConfig;
import emu.grasscutter.server.event.player.PlayerTeleportEvent;
import emu.grasscutter.server.event.player.PlayerTeleportEvent.TeleportType;
import emu.grasscutter.server.game.GameServer; import emu.grasscutter.server.game.GameServer;
import emu.grasscutter.server.packet.send.PacketDelTeamEntityNotify; import emu.grasscutter.server.packet.send.PacketDelTeamEntityNotify;
import emu.grasscutter.server.packet.send.PacketPlayerEnterSceneNotify; import emu.grasscutter.server.packet.send.PacketPlayerEnterSceneNotify;
@ -53,7 +55,7 @@ public class World implements Iterable<Player> {
this.players = Collections.synchronizedList(new ArrayList<>()); this.players = Collections.synchronizedList(new ArrayList<>());
this.scenes = Int2ObjectMaps.synchronize(new Int2ObjectOpenHashMap<>()); this.scenes = Int2ObjectMaps.synchronize(new Int2ObjectOpenHashMap<>());
this.levelEntityId = getNextEntityId(EntityIdType.MPLEVEL); this.levelEntityId = this.getNextEntityId(EntityIdType.MPLEVEL);
this.worldLevel = player.getWorldLevel(); this.worldLevel = player.getWorldLevel();
this.isMultiplayer = isMultiplayer; this.isMultiplayer = isMultiplayer;
@ -101,7 +103,7 @@ public class World implements Iterable<Player> {
public Scene getSceneById(int sceneId) { public Scene getSceneById(int sceneId) {
// Get scene normally // Get scene normally
Scene scene = getScenes().get(sceneId); Scene scene = this.getScenes().get(sceneId);
if (scene != null) { if (scene != null) {
return scene; return scene;
} }
@ -118,7 +120,7 @@ public class World implements Iterable<Player> {
} }
public int getPlayerCount() { public int getPlayerCount() {
return getPlayers().size(); return this.getPlayers().size();
} }
public boolean isMultiplayer() { public boolean isMultiplayer() {
@ -131,7 +133,7 @@ public class World implements Iterable<Player> {
public synchronized void addPlayer(Player player) { public synchronized void addPlayer(Player player) {
// Check if player already in // Check if player already in
if (getPlayers().contains(player)) { if (this.getPlayers().contains(player)) {
return; return;
} }
@ -142,11 +144,11 @@ public class World implements Iterable<Player> {
// Register // Register
player.setWorld(this); player.setWorld(this);
getPlayers().add(player); this.getPlayers().add(player);
// Set player variables // Set player variables
player.setPeerId(this.getNextPeerId()); player.setPeerId(this.getNextPeerId());
player.getTeamManager().setEntityId(getNextEntityId(EntityIdType.TEAM)); player.getTeamManager().setEntityId(this.getNextEntityId(EntityIdType.TEAM));
// Copy main team to multiplayer team // Copy main team to multiplayer team
if (this.isMultiplayer()) { if (this.isMultiplayer()) {
@ -169,12 +171,12 @@ public class World implements Iterable<Player> {
player.sendPacket( player.sendPacket(
new PacketDelTeamEntityNotify( new PacketDelTeamEntityNotify(
player.getSceneId(), player.getSceneId(),
getPlayers().stream().map(p -> p.getTeamManager().getEntityId()).collect(Collectors.toList()) this.getPlayers().stream().map(p -> p.getTeamManager().getEntityId()).collect(Collectors.toList())
) )
); );
// Deregister // Deregister
getPlayers().remove(player); this.getPlayers().remove(player);
player.setWorld(null); player.setWorld(null);
// Remove from scene // Remove from scene
@ -187,7 +189,7 @@ public class World implements Iterable<Player> {
} }
// Disband world if host leaves // Disband world if host leaves
if (getHost() == player) { if (this.getHost() == player) {
List<Player> kicked = new ArrayList<>(this.getPlayers()); List<Player> kicked = new ArrayList<>(this.getPlayers());
for (Player victim : kicked) { for (Player victim : kicked) {
World world = new World(victim); World world = new World(victim);
@ -207,14 +209,28 @@ public class World implements Iterable<Player> {
} }
public boolean transferPlayerToScene(Player player, int sceneId, Position pos) { public boolean transferPlayerToScene(Player player, int sceneId, Position pos) {
return transferPlayerToScene(player, sceneId, null, pos); return this.transferPlayerToScene(player, sceneId, TeleportType.INTERNAL, null, pos);
}
public boolean transferPlayerToScene(Player player, int sceneId, TeleportType teleportType, Position pos) {
return this.transferPlayerToScene(player, sceneId, teleportType, null, pos);
} }
public boolean transferPlayerToScene(Player player, int sceneId, DungeonData data) { public boolean transferPlayerToScene(Player player, int sceneId, DungeonData data) {
return transferPlayerToScene(player, sceneId, data, null); return this.transferPlayerToScene(player, sceneId, TeleportType.DUNGEON, data, null);
} }
public boolean transferPlayerToScene(Player player, int sceneId, DungeonData dungeonData, Position pos) { public boolean transferPlayerToScene(Player player, int sceneId, TeleportType teleportType, DungeonData dungeonData, Position teleportTo) {
// Call player teleport event.
PlayerTeleportEvent event = new PlayerTeleportEvent(player, teleportType, player.getPosition(), teleportTo);
// Call event & check if it was canceled.
event.call(); if (event.isCanceled()) {
return false; // Teleport was canceled.
}
// Set the destination.
teleportTo = event.getDestination();
if (GameData.getSceneDataMap().get(sceneId) == null) { if (GameData.getSceneDataMap().get(sceneId) == null) {
return false; return false;
} }
@ -224,7 +240,7 @@ public class World implements Iterable<Player> {
if (player.getScene() != null) { if (player.getScene() != null) {
oldScene = player.getScene(); oldScene = player.getScene();
// Dont deregister scenes if the player is going to tp back into them // Don't deregister scenes if the player is going to tp back into them
if (oldScene.getId() == sceneId) { if (oldScene.getId() == sceneId) {
oldScene.setDontDestroyWhenEmpty(true); oldScene.setDontDestroyWhenEmpty(true);
} }
@ -238,9 +254,9 @@ public class World implements Iterable<Player> {
// Dungeon // Dungeon
SceneConfig config = newScene.getScriptManager().getConfig(); SceneConfig config = newScene.getScriptManager().getConfig();
if (pos == null && config != null) { if (teleportTo == null && config != null) {
if (config.born_pos != null) { if (config.born_pos != null) {
pos = newScene.getScriptManager().getConfig().born_pos; teleportTo = newScene.getScriptManager().getConfig().born_pos;
} }
if (config.born_rot != null) { if (config.born_rot != null) {
player.getRotation().set(config.born_rot); player.getRotation().set(config.born_rot);
@ -248,11 +264,11 @@ public class World implements Iterable<Player> {
} }
// Set player position // Set player position
if (pos == null) { if (teleportTo == null) {
pos = player.getPosition(); teleportTo = player.getPosition();
} }
player.getPosition().set(pos); player.getPosition().set(teleportTo);
if (oldScene != null) { if (oldScene != null) {
newScene.setPrevScene(oldScene.getId()); newScene.setPrevScene(oldScene.getId());
@ -276,12 +292,12 @@ public class World implements Iterable<Player> {
} }
// Teleport packet // Teleport packet
player.sendPacket(new PacketPlayerEnterSceneNotify(player, enterType, enterReason, sceneId, pos)); player.sendPacket(new PacketPlayerEnterSceneNotify(player, enterType, enterReason, sceneId, teleportTo));
return true; return true;
} }
private void updatePlayerInfos(Player paramPlayer) { private void updatePlayerInfos(Player paramPlayer) {
for (Player player : getPlayers()) { for (Player player : this.getPlayers()) {
// Dont send packets if player is logging in and filter out joining player // Dont send packets if player is logging in and filter out joining player
if (!player.hasSentLoginPackets() || player == paramPlayer) { if (!player.hasSentLoginPackets() || player == paramPlayer) {
continue; continue;
@ -292,7 +308,7 @@ public class World implements Iterable<Player> {
player.getTeamManager().getMpTeam().copyFrom(player.getTeamManager().getMpTeam(), player.getTeamManager().getMaxTeamSize()); player.getTeamManager().getMpTeam().copyFrom(player.getTeamManager().getMpTeam(), player.getTeamManager().getMaxTeamSize());
player.getTeamManager().updateTeamEntities(null); player.getTeamManager().updateTeamEntities(null);
} }
// Dont send packets if player is loading into the scene // Dont send packets if player is loading into the scene
if (player.getSceneLoadState().getValue() < SceneLoadState.INIT.getValue() ) { if (player.getSceneLoadState().getValue() < SceneLoadState.INIT.getValue() ) {
// World player info packets // World player info packets
@ -326,6 +342,6 @@ public class World implements Iterable<Player> {
@Override @Override
public Iterator<Player> iterator() { public Iterator<Player> iterator() {
return getPlayers().iterator(); return this.getPlayers().iterator();
} }
} }

View File

@ -35,6 +35,11 @@ public final class PlayerTeleportEvent extends PlayerEvent implements Cancellabl
} }
public enum TeleportType { public enum TeleportType {
/**
* There is no specified reason to teleport.
*/
INTERNAL,
/** /**
* The player has asked to teleport to a waypoint. * The player has asked to teleport to a waypoint.
*/ */
@ -45,6 +50,11 @@ public final class PlayerTeleportEvent extends PlayerEvent implements Cancellabl
*/ */
MAP, MAP,
/**
* The player has asked to teleport into a dungeon.
*/
DUNGEON,
/** /**
* The player has asked to teleport using the command. * The player has asked to teleport using the command.
*/ */

View File

@ -5,9 +5,8 @@ import emu.grasscutter.data.binout.ScenePointEntry;
import emu.grasscutter.net.packet.Opcodes; import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.SceneTransToPointReqOuterClass.SceneTransToPointReq; import emu.grasscutter.net.proto.SceneTransToPointReqOuterClass.SceneTransToPointReq;
import emu.grasscutter.net.proto.SceneTransToPointRspOuterClass.SceneTransToPointRsp;
import emu.grasscutter.net.packet.PacketHandler; import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.server.event.player.PlayerTeleportEvent; import emu.grasscutter.server.event.player.PlayerTeleportEvent.TeleportType;
import emu.grasscutter.server.game.GameSession; import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketSceneTransToPointRsp; import emu.grasscutter.server.packet.send.PacketSceneTransToPointRsp;
import emu.grasscutter.utils.Position; import emu.grasscutter.utils.Position;
@ -27,14 +26,8 @@ public class HandlerSceneTransToPointReq extends PacketHandler {
float y = scenePointEntry.getPointData().getTranPos().getY(); float y = scenePointEntry.getPointData().getTranPos().getY();
float z = scenePointEntry.getPointData().getTranPos().getZ(); float z = scenePointEntry.getPointData().getTranPos().getZ();
PlayerTeleportEvent event = new PlayerTeleportEvent(session.getPlayer(), PlayerTeleportEvent.TeleportType.WAYPOINT, boolean result = session.getPlayer().getWorld().transferPlayerToScene(session.getPlayer(), req.getSceneId(), TeleportType.WAYPOINT, new Position(x, y, z));
session.getPlayer().getPosition(), new Position(x, y, z)); if(result) session.send(new PacketSceneTransToPointRsp(session.getPlayer(), req.getPointId(), req.getSceneId()));
event.call();
if(!event.isCanceled()) {
session.getPlayer().getWorld().transferPlayerToScene(session.getPlayer(), req.getSceneId(), new Position(x, y, z));
session.send(new PacketSceneTransToPointRsp(session.getPlayer(), req.getPointId(), req.getSceneId()));
}
} else { } else {
session.send(new PacketSceneTransToPointRsp()); session.send(new PacketSceneTransToPointRsp());
} }

View File

@ -1,15 +1,11 @@
package emu.grasscutter.server.packet.recv; package emu.grasscutter.server.packet.recv;
import emu.grasscutter.data.GameData;
import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.home.GameHome;
import emu.grasscutter.game.world.Scene; import emu.grasscutter.game.world.Scene;
import emu.grasscutter.net.packet.Opcodes; import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler; import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.TryEnterHomeReqOuterClass; import emu.grasscutter.net.proto.TryEnterHomeReqOuterClass;
import emu.grasscutter.scripts.data.SceneConfig; import emu.grasscutter.server.event.player.PlayerTeleportEvent.TeleportType;
import emu.grasscutter.server.event.player.PlayerTeleportEvent;
import emu.grasscutter.server.game.GameSession; import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketTryEnterHomeRsp; import emu.grasscutter.server.packet.send.PacketTryEnterHomeRsp;
import emu.grasscutter.utils.Position; import emu.grasscutter.utils.Position;
@ -39,17 +35,9 @@ public class HandlerTryEnterHomeReq extends PacketHandler {
Scene scene = session.getPlayer().getWorld().getSceneById(realmId); Scene scene = session.getPlayer().getWorld().getSceneById(realmId);
Position pos = scene.getScriptManager().getConfig().born_pos; Position pos = scene.getScriptManager().getConfig().born_pos;
PlayerTeleportEvent event = new PlayerTeleportEvent(session.getPlayer(), PlayerTeleportEvent.TeleportType.WAYPOINT, boolean result = session.getPlayer().getWorld().transferPlayerToScene(
session.getPlayer().getPosition(), pos); session.getPlayer(), realmId,
event.call(); TeleportType.WAYPOINT, pos
); if (result) session.send(new PacketTryEnterHomeRsp(req.getTargetUid()));
if(!event.isCanceled()) {
session.getPlayer().getWorld().transferPlayerToScene(
session.getPlayer(),
realmId, event.getDestination()
);
session.send(new PacketTryEnterHomeRsp(req.getTargetUid()));
}
} }
} }