Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: arrangement of main house is duplicated even if player changes module #2325

Merged
merged 5 commits into from
Sep 2, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 51 additions & 5 deletions src/main/java/emu/grasscutter/game/home/GameHome.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
import emu.grasscutter.game.props.SceneType;
import emu.grasscutter.server.packet.send.*;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import lombok.*;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.FieldDefaults;

import java.time.ZonedDateTime;
Expand Down Expand Up @@ -45,6 +47,7 @@ public class GameHome {
int storedFetterExp;
List<FurnitureMakeSlotItem> furnitureMakeSlotItemList;
ConcurrentHashMap<Integer, HomeSceneItem> sceneMap;
ConcurrentHashMap<Integer, HomeSceneItem> mainHouseMap;
Set<Integer> unlockedHomeBgmList;
int enterHomeOption;

Expand All @@ -53,6 +56,9 @@ public static GameHome getByUid(Integer uid) {
if (home == null) {
home = GameHome.create(uid);
}

home.fixMainHouseIfOld();

return home;
}

Expand All @@ -65,15 +71,32 @@ public static GameHome create(Integer uid) {
.ownerUid(uid)
.level(1)
.sceneMap(new ConcurrentHashMap<>())
.mainHouseMap(new ConcurrentHashMap<>())
.unlockedHomeBgmList(new HashSet<>())
.build();
}

// Data fixer.
private void fixMainHouseIfOld() {
if (this.getMainHouseMap() == null) {
Grasscutter.getLogger().info("player {} main house will be deleted due to GC update! sorry XD", this.getPlayer().getUid());
hamusuke0323 marked this conversation as resolved.
Show resolved Hide resolved
this.mainHouseMap = new ConcurrentHashMap<>(); // assign.
}

this.getSceneMap().values().removeIf(homeSceneItem -> homeSceneItem.getSceneId() > 2200);

this.save();
}

public void save() {
DatabaseHelper.saveHome(this);
}

public HomeSceneItem getHomeSceneItem(int sceneId) {
if (sceneId >= 2200) {
return this.getMainHouseItem(this.getPlayer().getCurrentRealmId() + 2000);
}

return sceneMap.computeIfAbsent(
sceneId,
e -> {
Expand All @@ -90,8 +113,31 @@ public HomeSceneItem getHomeSceneItem(int sceneId) {
});
}

public HomeSceneItem getMainHouseItem(int outdoorSceneId) {
return this.getMainHouseMap().computeIfAbsent(outdoorSceneId, integer -> {
var curHomeSceneItem = this.getHomeSceneItem(outdoorSceneId);
var roomSceneId = curHomeSceneItem.getRoomSceneId();
var defaultItem = GameData.getHomeworldDefaultSaveData().get(roomSceneId);
if (defaultItem == null) {
Grasscutter.getLogger().info("defaultItem == null! returns Liyue style house.");
return HomeSceneItem.parseFrom(GameData.getHomeworldDefaultSaveData().get(2202), 2202); // Liyue style
}

Grasscutter.getLogger().info("Set player {} main house {} to initial setting", this.ownerUid, roomSceneId);
return HomeSceneItem.parseFrom(defaultItem, roomSceneId);
});
}

public void onMainHouseChanged() {
Grasscutter.getLogger().debug("main house changed!");
var outdoor = this.getPlayer().getCurrentRealmId() + 2000;
this.getMainHouseMap().remove(outdoor); // delete main house in current scene.
this.getMainHouseItem(outdoor); // put new main house with default arrangement.
this.save();
}

public void onOwnerLogin(Player player) {
if (this.player == null) this.player = player;
this.player = player; // update player pointer. (prevent offline player from sending packet)
player.getSession().send(new PacketHomeBasicInfoNotify(player, false));
player.getSession().send(new PacketPlayerHomeCompInfoNotify(player));
player.getSession().send(new PacketHomeComfortInfoNotify(player));
Expand Down Expand Up @@ -217,10 +263,10 @@ public void takeHomeFetter(Player player) {
});

// Check as realm 5 inside is not in defaults and will be null
if (Objects.nonNull(sceneMap.get(player.getCurrentRealmId() + 2200))) {
if (Objects.nonNull(mainHouseMap.get(player.getCurrentRealmId() + 2000))) {
// Indoors avatars
sceneMap
.get(player.getCurrentRealmId() + 2200)
mainHouseMap
.get(player.getCurrentRealmId() + 2000)
.getBlockItems()
.forEach(
(i, e) -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
import emu.grasscutter.data.binout.HomeworldDefaultSaveData;
import emu.grasscutter.data.excels.ItemData;
import emu.grasscutter.game.world.Position;
import emu.grasscutter.net.proto.*;
import lombok.*;
import emu.grasscutter.net.proto.HomeFurnitureDataOuterClass;
import emu.grasscutter.net.proto.HomeMarkPointFurnitureDataOuterClass;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.FieldDefaults;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -66,7 +69,7 @@ public HomeFurnitureDataOuterClass.HomeFurnitureData toProto() {
}

public ItemData getAsItem() {
return GameData.getItemDataMap().get(this.furnitureId);
return this.furnitureId == 0 ? null : GameData.getItemDataMap().get(this.furnitureId);
}

public int getComfort() {
Expand Down
13 changes: 10 additions & 3 deletions src/main/java/emu/grasscutter/game/home/HomeSceneItem.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package emu.grasscutter.game.home;

import dev.morphia.annotations.*;
import dev.morphia.annotations.Entity;
import dev.morphia.annotations.Id;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.binout.HomeworldDefaultSaveData;
import emu.grasscutter.game.world.Position;
import emu.grasscutter.net.proto.HomeSceneArrangementInfoOuterClass.HomeSceneArrangementInfo;
import lombok.*;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.FieldDefaults;

import java.util.Map;
Expand Down Expand Up @@ -57,7 +60,11 @@ public void update(HomeSceneArrangementInfo arrangementInfo) {
this.bornRot = new Position(arrangementInfo.getBornRot());
this.djinnPos = new Position(arrangementInfo.getDjinnPos());
this.homeBgmId = arrangementInfo.getBgmId();
this.mainHouse = HomeFurnitureItem.parseFrom(arrangementInfo.getMainHouse());

if (!this.isRoom() && arrangementInfo.hasMainHouse()) {
this.mainHouse = HomeFurnitureItem.parseFrom(arrangementInfo.getMainHouse());
}

this.tmpVersion = arrangementInfo.getTmpVersion();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package emu.grasscutter.server.packet.recv;

import emu.grasscutter.game.world.*;
import emu.grasscutter.net.packet.*;
import emu.grasscutter.game.world.Position;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.HomeChangeModuleReqOuterClass;
import emu.grasscutter.server.event.player.PlayerTeleportEvent.TeleportType;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.*;
import emu.grasscutter.server.packet.send.PacketHomeChangeModuleRsp;
import emu.grasscutter.server.packet.send.PacketHomeComfortInfoNotify;
import emu.grasscutter.server.packet.send.PacketPlayerHomeCompInfoNotify;

@Opcodes(PacketOpcodes.HomeChangeModuleReq)
public class HandlerHomeChangeModuleReq extends PacketHandler {
Expand All @@ -14,6 +19,12 @@ public class HandlerHomeChangeModuleReq extends PacketHandler {
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
HomeChangeModuleReqOuterClass.HomeChangeModuleReq req =
HomeChangeModuleReqOuterClass.HomeChangeModuleReq.parseFrom(payload);

if (!session.getPlayer().getCurHomeWorld().getGuests().isEmpty()) {
session.send(new PacketHomeChangeModuleRsp());
return;
}

session.getPlayer().setCurrentRealmId(req.getTargetModuleId());
session.send(new PacketHomeChangeModuleRsp(req.getTargetModuleId()));
session.send(new PacketPlayerHomeCompInfoNotify(session.getPlayer()));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package emu.grasscutter.server.packet.recv;

import emu.grasscutter.net.packet.*;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.HomeSceneJumpReqOuterClass;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketHomeSceneJumpRsp;
Expand All @@ -21,7 +23,7 @@ public void handle(GameSession session, byte[] header, byte[] payload) throws Ex

var scene = world.getSceneById(req.getIsEnterRoomScene() ? homeScene.getRoomSceneId() : realmId);
var pos = scene.getScriptManager().getConfig().born_pos;
var rot = home.getSceneMap().get(scene.getId()).getBornRot();
var rot = home.getHomeSceneItem(scene.getId()).getBornRot();

// Make player face correct direction when entering or exiting
session.getPlayer().getRotation().set(rot);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package emu.grasscutter.server.packet.recv;

import emu.grasscutter.net.packet.*;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.HomeUpdateArrangementInfoReqOuterClass;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.*;
import emu.grasscutter.server.packet.send.PacketHomeBasicInfoNotify;
import emu.grasscutter.server.packet.send.PacketHomeMarkPointNotify;
import emu.grasscutter.server.packet.send.PacketHomeUpdateArrangementInfoRsp;

@Opcodes(PacketOpcodes.HomeUpdateArrangementInfoReq)
public class HandlerHomeUpdateArrangementInfoReq extends PacketHandler {
Expand All @@ -16,8 +20,13 @@ public void handle(GameSession session, byte[] header, byte[] payload) throws Ex
var homeScene =
session.getPlayer().getHome().getHomeSceneItem(session.getPlayer().getSceneId());

var roomSceneId = homeScene.getRoomSceneId();
homeScene.update(req.getSceneArrangementInfo());
if (roomSceneId != homeScene.getRoomSceneId()) {
session.getPlayer().getHome().onMainHouseChanged();
}

session.send(new PacketHomeBasicInfoNotify(session.getPlayer(), session.getPlayer().isInEditMode()));
session.send(new PacketHomeMarkPointNotify(session.getPlayer()));

session.getPlayer().getHome().save();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package emu.grasscutter.server.packet.send;

import emu.grasscutter.net.packet.*;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.HomeChangeModuleRspOuterClass;
import emu.grasscutter.net.proto.RetcodeOuterClass;

public class PacketHomeChangeModuleRsp extends BasePacket {

Expand All @@ -16,4 +18,11 @@ public PacketHomeChangeModuleRsp(int targetModuleId) {

this.setData(proto);
}

public PacketHomeChangeModuleRsp() {
super(PacketOpcodes.HomeChangeModuleRsp);

this.setData(HomeChangeModuleRspOuterClass.HomeChangeModuleRsp.newBuilder()
.setRetcode(RetcodeOuterClass.Retcode.RET_HOME_HAS_GUEST_VALUE));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@

import emu.grasscutter.game.home.HomeBlockItem;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.net.packet.*;
import emu.grasscutter.net.proto.*;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.HomeComfortInfoNotifyOuterClass;
import emu.grasscutter.net.proto.HomeModuleComfortInfoOuterClass;

import java.util.*;
import java.util.ArrayList;
import java.util.List;

public class PacketHomeComfortInfoNotify extends BasePacket {

Expand All @@ -23,7 +26,7 @@ public PacketHomeComfortInfoNotify(Player player) {
var homeScene = player.getHome().getHomeSceneItem(moduleId + 2000);
var blockComfortList =
homeScene.getBlockItems().values().stream().map(HomeBlockItem::calComfort).toList();
var homeRoomScene = player.getHome().getHomeSceneItem(homeScene.getRoomSceneId());
var homeRoomScene = player.getHome().getMainHouseItem(moduleId + 2000);

comfortInfoList.add(
HomeModuleComfortInfoOuterClass.HomeModuleComfortInfo.newBuilder()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package emu.grasscutter.server.packet.send;

import emu.grasscutter.game.home.*;
import emu.grasscutter.game.home.HomeBlockItem;
import emu.grasscutter.game.home.HomeMarkPointProtoFactory;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.net.packet.*;
import emu.grasscutter.net.proto.*;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.HomeMarkPointNotifyOuterClass;
import emu.grasscutter.net.proto.HomeMarkPointSceneDataOuterClass;

import java.util.Collection;
import java.util.Set;

public class PacketHomeMarkPointNotify extends BasePacket {

Expand All @@ -21,17 +25,24 @@ public PacketHomeMarkPointNotify(Player player) {
return;
}

for (var moduleId : owner.getRealmList()) {
var homeScene = home.getHomeSceneItem(moduleId + 2000);
// send current home mark points.
var moduleId = owner.getCurrentRealmId();
var homeScene = home.getHomeSceneItem(moduleId + 2000);
var mainHouse = home.getMainHouseItem(moduleId + 2000);

Set.of(homeScene, mainHouse).forEach(homeSceneItem -> {
var markPointData =
HomeMarkPointSceneDataOuterClass.HomeMarkPointSceneData.newBuilder()
.setModuleId(moduleId)
.setSceneId(moduleId + 2000)
.setSafePointPos(homeScene.isRoom() ? VectorOuterClass.Vector.newBuilder().build() : world.getSceneById(moduleId + 2000).getScriptManager().getConfig().born_pos.toProto())
.setTeapotSpiritPos(homeScene.isRoom() ? VectorOuterClass.Vector.newBuilder().build() : homeScene.getDjinnPos().toProto());
.setSceneId(homeSceneItem.getSceneId());

var marks = homeScene.getBlockItems().values().stream()
if (!homeSceneItem.isRoom()) {
var config = world.getSceneById(moduleId + 2000).getScriptManager().getConfig();
markPointData.setSafePointPos(config == null ? homeSceneItem.getBornPos().toProto() : config.born_pos.toProto())
.setTeapotSpiritPos(homeSceneItem.getDjinnPos().toProto());
}

var marks = homeSceneItem.getBlockItems().values().stream()
.map(HomeBlockItem::getMarkPointProtoFactories)
.flatMap(Collection::stream)
.filter(HomeMarkPointProtoFactory::isProtoConvertible)
Expand All @@ -40,7 +51,7 @@ public PacketHomeMarkPointNotify(Player player) {

markPointData.addAllFurnitureList(marks);
proto.addMarkPointDataList(markPointData);
}
});

this.setData(proto);
}
Expand Down