mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-12-14 07:55:57 +01:00
fix: NPE related to teapot when player logs in. (#2429)
* fix: NPE related to home when player logs in. * fix: NPE related to home when player logs in. * forgot to save player after fixing module id
This commit is contained in:
@@ -9,19 +9,21 @@ import emu.grasscutter.database.DatabaseHelper;
|
||||
import emu.grasscutter.game.avatar.Avatar;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.SceneType;
|
||||
import emu.grasscutter.net.proto.HomeAvatarTalkFinishInfoOuterClass;
|
||||
import emu.grasscutter.net.proto.HomeAvatarTalkFinishInfoOuterClass.HomeAvatarTalkFinishInfo;
|
||||
import emu.grasscutter.server.packet.send.*;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntSets;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@Entity(value = "homes", useDiscriminator = false)
|
||||
@Data
|
||||
@@ -36,6 +38,9 @@ public class GameHome {
|
||||
|| sceneData.getSceneType() == SceneType.SCENE_HOME_ROOM)
|
||||
.map(SceneData::getId)
|
||||
.collect(Collectors.toUnmodifiableSet());
|
||||
public static final Set<Integer> HOME_MODULE_IDS =
|
||||
GameData.getHomeWorldModuleDataMap().isEmpty() ?
|
||||
IntSets.fromTo(1, 6) : GameData.getHomeWorldModuleDataMap().keySet();
|
||||
|
||||
@Id String id;
|
||||
|
||||
@@ -181,6 +186,7 @@ public class GameHome {
|
||||
|
||||
public void onOwnerLogin(Player player) {
|
||||
this.player = player; // update player pointer. (prevent offline player from sending packet)
|
||||
this.fixModuleIdIfInvalid();
|
||||
player.getSession().send(new PacketHomeBasicInfoNotify(player, false));
|
||||
player.getSession().send(new PacketPlayerHomeCompInfoNotify(player));
|
||||
player.getSession().send(new PacketHomeComfortInfoNotify(player));
|
||||
@@ -194,6 +200,29 @@ public class GameHome {
|
||||
player.getSession().send(new PacketHomeResourceNotify(player));
|
||||
}
|
||||
|
||||
private void fixModuleIdIfInvalid() {
|
||||
if (this.player.hasSentLoginPackets() || this.player.getRealmList() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.player.getRealmList().removeIf(integer -> !HOME_MODULE_IDS.contains(integer)); // Delete invalid module ids.
|
||||
|
||||
if (this.player.getRealmList().isEmpty()) {
|
||||
this.player.setRealmList(null);
|
||||
this.player.save();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.player.getCurrentRealmId() <= 0 || !this.player.getCurHomeWorld().isRealmIdValid()) {
|
||||
int firstRId = this.player.getRealmList().iterator().next();
|
||||
this.player.setCurrentRealmId(firstRId);
|
||||
this.player.save();
|
||||
Grasscutter.getLogger().info("Set player {}'s current realm id to {} cuz the id is invalid.", this.player.getUid(), firstRId);
|
||||
}
|
||||
|
||||
this.player.getCurHomeWorld().refreshModuleManager(); // Apply module id fix.
|
||||
}
|
||||
|
||||
public void onPlayerChangedAvatarCostume(Avatar avatar) {
|
||||
var world = this.player.getServer().getHomeWorldOrCreate(this.player);
|
||||
world.broadcastPacket(
|
||||
@@ -239,7 +268,7 @@ public class GameHome {
|
||||
return this.finishedTalkIdMap.get(avatarId);
|
||||
}
|
||||
|
||||
public List<HomeAvatarTalkFinishInfoOuterClass.HomeAvatarTalkFinishInfo>
|
||||
public List<HomeAvatarTalkFinishInfo>
|
||||
toAvatarTalkFinishInfoProto() {
|
||||
if (this.finishedTalkIdMap == null) {
|
||||
this.finishedTalkIdMap = new HashMap<>();
|
||||
@@ -248,7 +277,7 @@ public class GameHome {
|
||||
return this.finishedTalkIdMap.entrySet().stream()
|
||||
.map(
|
||||
e -> {
|
||||
return HomeAvatarTalkFinishInfoOuterClass.HomeAvatarTalkFinishInfo.newBuilder()
|
||||
return HomeAvatarTalkFinishInfo.newBuilder()
|
||||
.setAvatarId(e.getKey())
|
||||
.addAllFinishTalkIdList(e.getValue())
|
||||
.build();
|
||||
|
||||
@@ -1,22 +1,25 @@
|
||||
package emu.grasscutter.game.home;
|
||||
|
||||
import com.github.davidmoten.guavamini.Lists;
|
||||
import emu.grasscutter.game.home.suite.HomeSuiteItem;
|
||||
import emu.grasscutter.game.home.suite.event.HomeAvatarRewardEvent;
|
||||
import emu.grasscutter.game.home.suite.event.HomeAvatarSummonEvent;
|
||||
import emu.grasscutter.game.home.suite.event.SuiteEventType;
|
||||
import emu.grasscutter.game.inventory.GameItem;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.net.proto.HomeAvatarRewardEventNotifyOuterClass;
|
||||
import emu.grasscutter.net.proto.HomeAvatarSummonAllEventNotifyOuterClass;
|
||||
import emu.grasscutter.net.proto.RetcodeOuterClass;
|
||||
import emu.grasscutter.net.proto.HomeAvatarRewardEventNotifyOuterClass.HomeAvatarRewardEventNotify;
|
||||
import emu.grasscutter.net.proto.HomeAvatarSummonAllEventNotifyOuterClass.HomeAvatarSummonAllEventNotify;
|
||||
import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
|
||||
import emu.grasscutter.server.packet.send.PacketHomeAvatarSummonAllEventNotify;
|
||||
import emu.grasscutter.utils.Either;
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Getter
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class HomeModuleManager {
|
||||
@@ -24,7 +27,9 @@ public class HomeModuleManager {
|
||||
final HomeWorld homeWorld;
|
||||
final GameHome home;
|
||||
final int moduleId;
|
||||
@Nullable
|
||||
final HomeScene outdoor;
|
||||
@Nullable
|
||||
HomeScene indoor;
|
||||
final List<HomeAvatarRewardEvent> rewardEvents;
|
||||
final List<HomeAvatarSummonEvent> summonEvents;
|
||||
@@ -45,8 +50,14 @@ public class HomeModuleManager {
|
||||
return;
|
||||
}
|
||||
|
||||
this.outdoor.onTick();
|
||||
this.indoor.onTick();
|
||||
if (this.outdoor != null) {
|
||||
this.outdoor.onTick();
|
||||
}
|
||||
|
||||
if (this.indoor != null) {
|
||||
this.indoor.onTick();
|
||||
}
|
||||
|
||||
this.summonEvents.removeIf(HomeAvatarSummonEvent::isTimeOver);
|
||||
}
|
||||
|
||||
@@ -66,44 +77,45 @@ public class HomeModuleManager {
|
||||
private void fireAllAvatarRewardEvents() {
|
||||
this.rewardEvents.clear();
|
||||
var allBlockItems =
|
||||
Stream.of(this.getOutdoorSceneItem(), this.getIndoorSceneItem())
|
||||
.map(HomeSceneItem::getBlockItems)
|
||||
.map(Map::values)
|
||||
.flatMap(Collection::stream)
|
||||
.toList();
|
||||
Stream.of(this.getOutdoorSceneItem(), this.getIndoorSceneItem())
|
||||
.filter(Objects::nonNull)
|
||||
.map(HomeSceneItem::getBlockItems)
|
||||
.map(Map::values)
|
||||
.flatMap(Collection::stream)
|
||||
.toList();
|
||||
|
||||
var suites =
|
||||
allBlockItems.stream()
|
||||
.map(HomeBlockItem::getSuiteList)
|
||||
.filter(Objects::nonNull)
|
||||
.flatMap(Collection::stream)
|
||||
.distinct()
|
||||
.toList();
|
||||
allBlockItems.stream()
|
||||
.map(HomeBlockItem::getSuiteList)
|
||||
.filter(Objects::nonNull)
|
||||
.flatMap(Collection::stream)
|
||||
.distinct()
|
||||
.toList();
|
||||
|
||||
allBlockItems.stream()
|
||||
.map(HomeBlockItem::getDeployNPCList)
|
||||
.flatMap(Collection::stream)
|
||||
.forEach(
|
||||
avatar -> {
|
||||
suites.forEach(
|
||||
suite -> {
|
||||
var data =
|
||||
SuiteEventType.HOME_AVATAR_REWARD_EVENT.getEventDataFrom(
|
||||
avatar.getAvatarId(), suite.getSuiteId());
|
||||
if (data == null || this.home.isRewardEventFinished(data.getId())) {
|
||||
return;
|
||||
}
|
||||
.map(HomeBlockItem::getDeployNPCList)
|
||||
.flatMap(Collection::stream)
|
||||
.forEach(
|
||||
avatar -> {
|
||||
suites.forEach(
|
||||
suite -> {
|
||||
var data =
|
||||
SuiteEventType.HOME_AVATAR_REWARD_EVENT.getEventDataFrom(
|
||||
avatar.getAvatarId(), suite.getSuiteId());
|
||||
if (data == null || this.home.isRewardEventFinished(data.getId())) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.rewardEvents.add(
|
||||
new HomeAvatarRewardEvent(
|
||||
homeOwner,
|
||||
data.getId(),
|
||||
data.getRewardID(),
|
||||
data.getAvatarID(),
|
||||
data.getSuiteId(),
|
||||
suite.getGuid()));
|
||||
});
|
||||
this.rewardEvents.add(
|
||||
new HomeAvatarRewardEvent(
|
||||
homeOwner,
|
||||
data.getId(),
|
||||
data.getRewardID(),
|
||||
data.getAvatarID(),
|
||||
data.getSuiteId(),
|
||||
suite.getGuid()));
|
||||
});
|
||||
});
|
||||
|
||||
if (this.summonEvents != null) {
|
||||
var suiteIdList = this.rewardEvents.stream().map(HomeAvatarRewardEvent::getSuiteId).toList();
|
||||
@@ -113,68 +125,71 @@ public class HomeModuleManager {
|
||||
|
||||
private void cancelSummonEventsIfAvatarLeave() {
|
||||
var avatars =
|
||||
Stream.of(this.getOutdoorSceneItem(), this.getIndoorSceneItem())
|
||||
.map(HomeSceneItem::getBlockItems)
|
||||
.map(Map::values)
|
||||
.flatMap(Collection::stream)
|
||||
.map(HomeBlockItem::getDeployNPCList)
|
||||
.flatMap(Collection::stream)
|
||||
.map(HomeNPCItem::getAvatarId)
|
||||
.toList();
|
||||
Stream.of(this.getOutdoorSceneItem(), this.getIndoorSceneItem())
|
||||
.filter(Objects::nonNull)
|
||||
.map(HomeSceneItem::getBlockItems)
|
||||
.map(Map::values)
|
||||
.flatMap(Collection::stream)
|
||||
.map(HomeBlockItem::getDeployNPCList)
|
||||
.flatMap(Collection::stream)
|
||||
.map(HomeNPCItem::getAvatarId)
|
||||
.toList();
|
||||
|
||||
this.summonEvents.removeIf(event -> !avatars.contains(event.getAvatarId()));
|
||||
}
|
||||
|
||||
public Either<List<GameItem>, Integer> claimAvatarRewards(int eventId) {
|
||||
if (this.rewardEvents.isEmpty()) {
|
||||
return Either.right(RetcodeOuterClass.Retcode.RET_FAIL_VALUE);
|
||||
return Either.right(Retcode.RET_FAIL_VALUE);
|
||||
}
|
||||
|
||||
var event = this.rewardEvents.remove(0);
|
||||
if (event.getEventId() != eventId) {
|
||||
return Either.right(RetcodeOuterClass.Retcode.RET_FAIL_VALUE);
|
||||
return Either.right(Retcode.RET_FAIL_VALUE);
|
||||
}
|
||||
|
||||
if (!this.homeOwner.getHome().onClaimAvatarRewards(eventId)) {
|
||||
return Either.right(RetcodeOuterClass.Retcode.RET_FAIL_VALUE);
|
||||
return Either.right(Retcode.RET_FAIL_VALUE);
|
||||
}
|
||||
|
||||
return Either.left(event.giveRewards());
|
||||
}
|
||||
|
||||
public Either<HomeAvatarSummonEvent, Integer> fireAvatarSummonEvent(
|
||||
Player owner, int avatarId, int guid, int suiteId) {
|
||||
var targetSuite =
|
||||
((HomeScene) owner.getScene())
|
||||
.getSceneItem().getBlockItems().values().stream()
|
||||
.map(HomeBlockItem::getSuiteList)
|
||||
.flatMap(Collection::stream)
|
||||
.filter(suite -> suite.getGuid() == guid)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
Player owner, int avatarId, int guid, int suiteId) {
|
||||
HomeSuiteItem targetSuite = null;
|
||||
if (owner.getScene() instanceof HomeScene homeScene) {
|
||||
targetSuite = homeScene
|
||||
.getSceneItem().getBlockItems().values().stream()
|
||||
.map(HomeBlockItem::getSuiteList)
|
||||
.flatMap(Collection::stream)
|
||||
.filter(suite -> suite.getGuid() == guid)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
if (this.isInRewardEvent(avatarId)) {
|
||||
return Either.right(RetcodeOuterClass.Retcode.RET_DUPLICATE_AVATAR_VALUE);
|
||||
return Either.right(Retcode.RET_DUPLICATE_AVATAR_VALUE);
|
||||
}
|
||||
|
||||
if (this.rewardEvents.stream().anyMatch(event -> event.getGuid() == guid)) {
|
||||
return Either.right(RetcodeOuterClass.Retcode.RET_HOME_FURNITURE_GUID_ERROR_VALUE);
|
||||
return Either.right(Retcode.RET_HOME_FURNITURE_GUID_ERROR_VALUE);
|
||||
}
|
||||
|
||||
this.summonEvents.removeIf(event -> event.getGuid() == guid || event.getAvatarId() == avatarId);
|
||||
|
||||
if (targetSuite == null) {
|
||||
return Either.right(RetcodeOuterClass.Retcode.RET_HOME_CLIENT_PARAM_INVALID_VALUE);
|
||||
return Either.right(Retcode.RET_HOME_CLIENT_PARAM_INVALID_VALUE);
|
||||
}
|
||||
|
||||
var eventData = SuiteEventType.HOME_AVATAR_SUMMON_EVENT.getEventDataFrom(avatarId, suiteId);
|
||||
if (eventData == null) {
|
||||
return Either.right(RetcodeOuterClass.Retcode.RET_HOME_CLIENT_PARAM_INVALID_VALUE);
|
||||
return Either.right(Retcode.RET_HOME_CLIENT_PARAM_INVALID_VALUE);
|
||||
}
|
||||
|
||||
var event =
|
||||
new HomeAvatarSummonEvent(
|
||||
owner, eventData.getId(), eventData.getRewardID(), avatarId, suiteId, guid);
|
||||
new HomeAvatarSummonEvent(
|
||||
owner, eventData.getId(), eventData.getRewardID(), avatarId, suiteId, guid);
|
||||
this.summonEvents.add(event);
|
||||
owner.sendPacket(new PacketHomeAvatarSummonAllEventNotify(owner));
|
||||
return Either.left(event);
|
||||
@@ -184,38 +199,39 @@ public class HomeModuleManager {
|
||||
this.summonEvents.removeIf(event -> event.getEventId() == eventId);
|
||||
}
|
||||
|
||||
public HomeAvatarRewardEventNotifyOuterClass.HomeAvatarRewardEventNotify toRewardEventProto() {
|
||||
var notify = HomeAvatarRewardEventNotifyOuterClass.HomeAvatarRewardEventNotify.newBuilder();
|
||||
public HomeAvatarRewardEventNotify toRewardEventProto() {
|
||||
var notify = HomeAvatarRewardEventNotify.newBuilder();
|
||||
if (!this.rewardEvents.isEmpty()) {
|
||||
notify.setRewardEvent(this.rewardEvents.get(0).toProto()).setIsEventTrigger(true);
|
||||
|
||||
notify.addAllPendingList(
|
||||
this.rewardEvents.subList(1, this.rewardEvents.size()).stream()
|
||||
.map(HomeAvatarRewardEvent::toProto)
|
||||
.toList());
|
||||
this.rewardEvents.subList(1, this.rewardEvents.size()).stream()
|
||||
.map(HomeAvatarRewardEvent::toProto)
|
||||
.toList());
|
||||
}
|
||||
|
||||
return notify.build();
|
||||
}
|
||||
|
||||
public HomeAvatarSummonAllEventNotifyOuterClass.HomeAvatarSummonAllEventNotify
|
||||
toSummonEventProto() {
|
||||
return HomeAvatarSummonAllEventNotifyOuterClass.HomeAvatarSummonAllEventNotify.newBuilder()
|
||||
.addAllSummonEventList(
|
||||
this.summonEvents.stream().map(HomeAvatarSummonEvent::toProto).toList())
|
||||
.build();
|
||||
public HomeAvatarSummonAllEventNotify toSummonEventProto() {
|
||||
return HomeAvatarSummonAllEventNotify.newBuilder()
|
||||
.addAllSummonEventList(
|
||||
this.summonEvents.stream().map(HomeAvatarSummonEvent::toProto).toList())
|
||||
.build();
|
||||
}
|
||||
|
||||
public boolean isInRewardEvent(int avatarId) {
|
||||
return this.rewardEvents.stream().anyMatch(e -> e.getAvatarId() == avatarId);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public HomeSceneItem getOutdoorSceneItem() {
|
||||
return this.outdoor.getSceneItem();
|
||||
return this.outdoor == null ? null : this.outdoor.getSceneItem();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public HomeSceneItem getIndoorSceneItem() {
|
||||
return this.indoor.getSceneItem();
|
||||
return this.indoor == null ? null : this.indoor.getSceneItem();
|
||||
}
|
||||
|
||||
public void onSetModule() {
|
||||
@@ -223,8 +239,14 @@ public class HomeModuleManager {
|
||||
return;
|
||||
}
|
||||
|
||||
this.outdoor.addEntities(this.getOutdoorSceneItem().getAnimals(this.outdoor));
|
||||
this.indoor.addEntities(this.getIndoorSceneItem().getAnimals(this.indoor));
|
||||
if (this.outdoor != null) {
|
||||
this.outdoor.addEntities(this.getOutdoorSceneItem().getAnimals(this.outdoor));
|
||||
}
|
||||
|
||||
if (this.indoor != null) {
|
||||
this.indoor.addEntities(this.getIndoorSceneItem().getAnimals(this.indoor));
|
||||
}
|
||||
|
||||
this.fireAllAvatarRewardEvents();
|
||||
}
|
||||
|
||||
@@ -233,7 +255,12 @@ public class HomeModuleManager {
|
||||
return;
|
||||
}
|
||||
|
||||
this.outdoor.getEntities().clear();
|
||||
this.indoor.getEntities().clear();
|
||||
if (this.outdoor != null) {
|
||||
this.outdoor.getEntities().clear();
|
||||
}
|
||||
|
||||
if (this.indoor != null) {
|
||||
this.indoor.getEntities().clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package emu.grasscutter.game.home;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.game.entity.EntityTeam;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
import emu.grasscutter.game.world.World;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.proto.ChatInfoOuterClass;
|
||||
@@ -11,9 +10,11 @@ import emu.grasscutter.server.game.GameServer;
|
||||
import emu.grasscutter.server.packet.send.PacketDelTeamEntityNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketPlayerChatNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketPlayerGameTimeNotify;
|
||||
import lombok.Getter;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class HomeWorld extends World {
|
||||
@@ -66,7 +67,7 @@ public class HomeWorld extends World {
|
||||
}
|
||||
|
||||
public boolean isRealmIdValid() {
|
||||
return this.getHost().getCurrentRealmId() > 0;
|
||||
return this.getSceneById(this.getHost().getCurrentRealmId() + 2000) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -147,11 +148,13 @@ public class HomeWorld extends World {
|
||||
player.setWorld(null);
|
||||
|
||||
// Remove from scene
|
||||
Scene scene = this.getSceneById(player.getSceneId());
|
||||
scene.removePlayer(player);
|
||||
var scene = this.getSceneById(player.getSceneId());
|
||||
if (scene != null) {
|
||||
scene.removePlayer(player);
|
||||
}
|
||||
|
||||
// Info packet for other players
|
||||
if (this.getPlayers().size() > 0) {
|
||||
if (!this.getPlayers().isEmpty()) {
|
||||
this.updatePlayerInfos(player);
|
||||
}
|
||||
|
||||
@@ -167,6 +170,7 @@ public class HomeWorld extends World {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public HomeScene getSceneById(int sceneId) {
|
||||
var scene = this.getScenes().get(sceneId);
|
||||
if (scene instanceof HomeScene homeScene) {
|
||||
|
||||
@@ -139,11 +139,18 @@ public class HomeWorldMPSystem extends BaseGameSystem {
|
||||
|
||||
int realmId = 2000 + owner.getCurrentRealmId();
|
||||
var item = targetHome.getHomeSceneItem(realmId);
|
||||
var scene = world.getSceneById(realmId);
|
||||
targetHome.save();
|
||||
var pos =
|
||||
|
||||
Position pos;
|
||||
if (scene != null) {
|
||||
pos =
|
||||
toSafe
|
||||
? world.getSceneById(realmId).getScriptManager().getConfig().born_pos
|
||||
: item.getBornPos();
|
||||
? scene.getScriptManager().getConfig().born_pos
|
||||
: item.getBornPos();
|
||||
} else {
|
||||
pos = item.getBornPos();
|
||||
}
|
||||
|
||||
if (teleportPoint != 0) {
|
||||
var target = item.getTeleportPointPos(teleportPoint);
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
package emu.grasscutter.game.world;
|
||||
|
||||
import static emu.grasscutter.server.event.player.PlayerTeleportEvent.TeleportType.SCRIPT;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.dungeon.DungeonData;
|
||||
import emu.grasscutter.game.entity.*;
|
||||
import emu.grasscutter.game.entity.EntityTeam;
|
||||
import emu.grasscutter.game.entity.EntityWorld;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.player.Player.SceneLoadState;
|
||||
import emu.grasscutter.game.props.*;
|
||||
import emu.grasscutter.game.props.EnterReason;
|
||||
import emu.grasscutter.game.props.EntityIdType;
|
||||
import emu.grasscutter.game.props.PlayerProperty;
|
||||
import emu.grasscutter.game.props.SceneType;
|
||||
import emu.grasscutter.game.quest.enums.QuestContent;
|
||||
import emu.grasscutter.game.world.data.TeleportProperties;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.proto.ChatInfoOuterClass.ChatInfo.*;
|
||||
import emu.grasscutter.net.proto.ChatInfoOuterClass.ChatInfo.SystemHint;
|
||||
import emu.grasscutter.net.proto.ChatInfoOuterClass.ChatInfo.SystemHintType;
|
||||
import emu.grasscutter.net.proto.EnterTypeOuterClass.EnterType;
|
||||
import emu.grasscutter.scripts.data.SceneConfig;
|
||||
import emu.grasscutter.server.event.player.PlayerTeleportEvent;
|
||||
@@ -21,12 +24,25 @@ import emu.grasscutter.server.game.GameServer;
|
||||
import emu.grasscutter.server.packet.send.*;
|
||||
import emu.grasscutter.utils.ConversionUtils;
|
||||
import io.netty.util.concurrent.FastThreadLocalThread;
|
||||
import it.unimi.dsi.fastutil.ints.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import lombok.*;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import lombok.Getter;
|
||||
import lombok.val;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static emu.grasscutter.server.event.player.PlayerTeleportEvent.TeleportType.SCRIPT;
|
||||
|
||||
public class World implements Iterable<Player> {
|
||||
@Getter private final GameServer server;
|
||||
@Getter private Player host;
|
||||
@@ -124,6 +140,7 @@ public class World implements Iterable<Player> {
|
||||
* @param sceneId The scene ID.
|
||||
* @return The scene.
|
||||
*/
|
||||
@Nullable
|
||||
public Scene getSceneById(int sceneId) {
|
||||
// Get scene normally
|
||||
var scene = this.getScenes().get(sceneId);
|
||||
|
||||
Reference in New Issue
Block a user