mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-12-16 17:05:20 +01:00
feat: support multiplayer mode in teapot (#2317)
This commit is contained in:
@@ -4,31 +4,40 @@ import dev.morphia.annotations.*;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.HomeWorldLevelData;
|
||||
import emu.grasscutter.data.excels.scene.SceneData;
|
||||
import emu.grasscutter.database.DatabaseHelper;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.SceneType;
|
||||
import emu.grasscutter.server.packet.send.*;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
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 lombok.AccessLevel;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@Entity(value = "homes", useDiscriminator = false)
|
||||
@Data
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
@Builder(builderMethodName = "of")
|
||||
public class GameHome {
|
||||
@Id String id;
|
||||
public static final Set<Integer> HOME_SCENE_IDS = GameData.getSceneDataMap().values().stream()
|
||||
.filter(sceneData -> sceneData.getSceneType() == SceneType.SCENE_HOME_WORLD || sceneData.getSceneType() == SceneType.SCENE_HOME_ROOM)
|
||||
.map(SceneData::getId).collect(Collectors.toUnmodifiableSet());
|
||||
|
||||
@Id
|
||||
String id;
|
||||
|
||||
@Indexed(options = @IndexOptions(unique = true))
|
||||
long ownerUid;
|
||||
|
||||
@Transient Player player;
|
||||
@Transient
|
||||
Player player;
|
||||
|
||||
int level;
|
||||
int exp;
|
||||
@@ -49,13 +58,17 @@ public class GameHome {
|
||||
return home;
|
||||
}
|
||||
|
||||
public static boolean doesHomeExist(int uid) {
|
||||
return DatabaseHelper.getHomeByUid(uid) != null;
|
||||
}
|
||||
|
||||
public static GameHome create(Integer uid) {
|
||||
return GameHome.of()
|
||||
.ownerUid(uid)
|
||||
.level(1)
|
||||
.sceneMap(new ConcurrentHashMap<>())
|
||||
.unlockedHomeBgmList(new HashSet<>())
|
||||
.build();
|
||||
.ownerUid(uid)
|
||||
.level(1)
|
||||
.sceneMap(new ConcurrentHashMap<>())
|
||||
.unlockedHomeBgmList(new HashSet<>())
|
||||
.build();
|
||||
}
|
||||
|
||||
public void save() {
|
||||
@@ -64,19 +77,19 @@ public class GameHome {
|
||||
|
||||
public HomeSceneItem getHomeSceneItem(int sceneId) {
|
||||
return sceneMap.computeIfAbsent(
|
||||
sceneId,
|
||||
e -> {
|
||||
var defaultItem = GameData.getHomeworldDefaultSaveData().get(sceneId);
|
||||
if (defaultItem != null) {
|
||||
Grasscutter.getLogger()
|
||||
.info("Set player {} home {} to initial setting", ownerUid, sceneId);
|
||||
return HomeSceneItem.parseFrom(defaultItem, sceneId);
|
||||
} else {
|
||||
// Realm res missing bricks account, use default realm data to allow main house
|
||||
defaultItem = GameData.getHomeworldDefaultSaveData().get(2001);
|
||||
return HomeSceneItem.parseFrom(defaultItem, sceneId);
|
||||
}
|
||||
});
|
||||
sceneId,
|
||||
e -> {
|
||||
var defaultItem = GameData.getHomeworldDefaultSaveData().get(sceneId);
|
||||
if (defaultItem != null) {
|
||||
Grasscutter.getLogger()
|
||||
.info("Set player {} home {} to initial setting", ownerUid, sceneId);
|
||||
return HomeSceneItem.parseFrom(defaultItem, sceneId);
|
||||
} else {
|
||||
// Realm res missing bricks account, use default realm data to allow main house
|
||||
defaultItem = GameData.getHomeworldDefaultSaveData().get(2001);
|
||||
return HomeSceneItem.parseFrom(defaultItem, sceneId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void onOwnerLogin(Player player) {
|
||||
@@ -130,9 +143,9 @@ public class GameHome {
|
||||
|
||||
private Set<Integer> getDefaultUnlockedHomeBgmIds() {
|
||||
return GameData.getHomeWorldBgmDataMap().int2ObjectEntrySet().stream()
|
||||
.filter(e -> e.getValue().isDefaultUnlock())
|
||||
.map(Int2ObjectMap.Entry::getIntKey)
|
||||
.collect(Collectors.toUnmodifiableSet());
|
||||
.filter(e -> e.getValue().isDefaultUnlock())
|
||||
.map(Int2ObjectMap.Entry::getIntKey)
|
||||
.collect(Collectors.toUnmodifiableSet());
|
||||
}
|
||||
|
||||
// Same as Player.java addExpDirectly
|
||||
@@ -171,7 +184,7 @@ public class GameHome {
|
||||
|
||||
// Ensure next update is at top of the hour
|
||||
nextUpdateTime =
|
||||
(int) ZonedDateTime.now().plusHours(1).truncatedTo(ChronoUnit.HOURS).toEpochSecond();
|
||||
(int) ZonedDateTime.now().plusHours(1).truncatedTo(ChronoUnit.HOURS).toEpochSecond();
|
||||
|
||||
// Get resources
|
||||
var hourlyResources = getComfortResources(player);
|
||||
@@ -194,42 +207,42 @@ public class GameHome {
|
||||
|
||||
// Outdoors avatars
|
||||
sceneMap
|
||||
.get(player.getCurrentRealmId() + 2000)
|
||||
.getBlockItems()
|
||||
.forEach(
|
||||
(i, e) -> {
|
||||
e.getDeployNPCList()
|
||||
.forEach(
|
||||
id -> {
|
||||
invitedAvatars.add(id.getAvatarId());
|
||||
});
|
||||
});
|
||||
.get(player.getCurrentRealmId() + 2000)
|
||||
.getBlockItems()
|
||||
.forEach(
|
||||
(i, e) -> {
|
||||
e.getDeployNPCList()
|
||||
.forEach(
|
||||
id -> {
|
||||
invitedAvatars.add(id.getAvatarId());
|
||||
});
|
||||
});
|
||||
|
||||
// Check as realm 5 inside is not in defaults and will be null
|
||||
if (Objects.nonNull(sceneMap.get(player.getCurrentRealmId() + 2200))) {
|
||||
// Indoors avatars
|
||||
sceneMap
|
||||
.get(player.getCurrentRealmId() + 2200)
|
||||
.getBlockItems()
|
||||
.forEach(
|
||||
(i, e) -> {
|
||||
e.getDeployNPCList()
|
||||
.forEach(
|
||||
id -> {
|
||||
invitedAvatars.add(id.getAvatarId());
|
||||
});
|
||||
});
|
||||
.get(player.getCurrentRealmId() + 2200)
|
||||
.getBlockItems()
|
||||
.forEach(
|
||||
(i, e) -> {
|
||||
e.getDeployNPCList()
|
||||
.forEach(
|
||||
id -> {
|
||||
invitedAvatars.add(id.getAvatarId());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Add exp to all avatars
|
||||
invitedAvatars.forEach(
|
||||
id -> {
|
||||
var avatar = player.getAvatars().getAvatarById(id);
|
||||
player
|
||||
.getServer()
|
||||
.getInventorySystem()
|
||||
.upgradeAvatarFetterLevel(player, avatar, storedFetterExp);
|
||||
});
|
||||
id -> {
|
||||
var avatar = player.getAvatars().getAvatarById(id);
|
||||
player
|
||||
.getServer()
|
||||
.getInventorySystem()
|
||||
.upgradeAvatarFetterLevel(player, avatar, storedFetterExp);
|
||||
});
|
||||
|
||||
storedFetterExp = 0;
|
||||
save();
|
||||
@@ -253,7 +266,7 @@ public class GameHome {
|
||||
storeResources(player, 0, 0);
|
||||
lastUpdatedTime = clientTime;
|
||||
nextUpdateTime =
|
||||
(int) ZonedDateTime.now().plusHours(1).truncatedTo(ChronoUnit.HOURS).toEpochSecond();
|
||||
(int) ZonedDateTime.now().plusHours(1).truncatedTo(ChronoUnit.HOURS).toEpochSecond();
|
||||
save();
|
||||
|
||||
// Send packet
|
||||
|
||||
Reference in New Issue
Block a user