diff --git a/proto/MusicBriefInfo.proto b/proto/MusicBriefInfo.proto index 6b9ae2878..160e361c3 100644 --- a/proto/MusicBriefInfo.proto +++ b/proto/MusicBriefInfo.proto @@ -11,14 +11,14 @@ message MusicBriefInfo { uint32 score = 6; uint32 create_time = 7; uint32 share_time = 8; - uint32 DOANBAODBMA = 9; + uint32 position = 9; bool settle = 10; uint32 version = 11; bool can_share = 12; bool OAPKHNELBPH = 13; bool NJHAMJMHPAA = 14; uint64 ADIBIKKNPKK = 15; - uint32 save_position = 21; + uint32 unknown = 21; repeated uint32 GIDFMAJFIFE = 22; repeated uint32 OKBJPAKOLIH = 23; uint32 FAOPBAMDFJB = 24; diff --git a/proto/MusicGameStartToPlayOthersBeatmapReq.proto b/proto/MusicGameStartToPlayOthersBeatmapReq.proto new file mode 100644 index 000000000..3c7e9e8e8 --- /dev/null +++ b/proto/MusicGameStartToPlayOthersBeatmapReq.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +option java_package = "emu.grasscutter.net.proto"; + +import "MusicGameUnknown1Enum.proto"; + +// CmdId: 6302 +// EnetChannelId: 0 +// EnetIsReliable: true +// IsAllowClient: true +message MusicGameStartToPlayOthersBeatmapReq { + MusicGameUnknown1Enum unknown_enum1 = 12; +} diff --git a/proto/MusicGameStartToPlayOthersBeatmapRsp.proto b/proto/MusicGameStartToPlayOthersBeatmapRsp.proto new file mode 100644 index 000000000..7e62025b7 --- /dev/null +++ b/proto/MusicGameStartToPlayOthersBeatmapRsp.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +option java_package = "emu.grasscutter.net.proto"; + +import "MusicGameUnknown1Enum.proto"; + +// CmdId: 6313 +// EnetChannelId: 0 +// EnetIsReliable: true +message MusicGameStartToPlayOthersBeatmapRsp { + int32 retcode = 2; + MusicGameUnknown1Enum unknown_enum1 = 11; + repeated uint64 AMNODOLNOIM = 6; +} diff --git a/src/main/java/emu/grasscutter/game/activity/musicgame/MusicGameActivityHandler.java b/src/main/java/emu/grasscutter/game/activity/musicgame/MusicGameActivityHandler.java index 0dcb0ae55..1fec26c56 100644 --- a/src/main/java/emu/grasscutter/game/activity/musicgame/MusicGameActivityHandler.java +++ b/src/main/java/emu/grasscutter/game/activity/musicgame/MusicGameActivityHandler.java @@ -23,7 +23,7 @@ public class MusicGameActivityHandler extends ActivityHandler { @Override public void onProtoBuild(PlayerActivityData playerActivityData, ActivityInfoOuterClass.ActivityInfo.Builder activityInfo) { - MusicGamePlayerData musicGamePlayerData = getMusicGameRecord(playerActivityData); + MusicGamePlayerData musicGamePlayerData = getMusicGamePlayerData(playerActivityData); activityInfo.setMusicGameInfo(MusicGameActivityDetailInfoOuterClass.MusicGameActivityDetailInfo.newBuilder() .putAllMusicGameRecordMap( @@ -31,18 +31,18 @@ public class MusicGameActivityHandler extends ActivityHandler { .collect(Collectors.toMap(MusicGamePlayerData.MusicGameRecord::getMusicId, MusicGamePlayerData.MusicGameRecord::toProto))) .addAllPersonCustomBeatmap(musicGamePlayerData.getPersonalCustomBeatmapRecord().values().stream() - .map(MusicGamePlayerData.CustomBeatmapRecord::toProto) + .map(MusicGamePlayerData.CustomBeatmapRecord::toPersonalBriefProto) .map(MusicBriefInfoOuterClass.MusicBriefInfo.Builder::build) .toList()) .addAllPersonCustomBeatmap(musicGamePlayerData.getOthersCustomBeatmapRecord().values().stream() - .map(MusicGamePlayerData.CustomBeatmapRecord::toProto) + .map(MusicGamePlayerData.CustomBeatmapRecord::toOthersBriefProto) .map(MusicBriefInfoOuterClass.MusicBriefInfo.Builder::build) .toList()) .build()); } - public MusicGamePlayerData getMusicGameRecord(PlayerActivityData playerActivityData){ + public MusicGamePlayerData getMusicGamePlayerData(PlayerActivityData playerActivityData){ if(playerActivityData.getDetail() == null || playerActivityData.getDetail().isBlank()){ onInitPlayerActivityData(playerActivityData); playerActivityData.save(); @@ -53,7 +53,7 @@ public class MusicGameActivityHandler extends ActivityHandler { } public boolean setMusicGameRecord(PlayerActivityData playerActivityData, MusicGamePlayerData.MusicGameRecord newRecord){ - var musicGamePlayerData = getMusicGameRecord(playerActivityData); + var musicGamePlayerData = getMusicGamePlayerData(playerActivityData); var saveRecord = musicGamePlayerData.getMusicGameRecord().get(newRecord.getMusicId()); saveRecord.setMaxCombo(Math.max(newRecord.getMaxCombo(), saveRecord.getMaxCombo())); @@ -65,7 +65,7 @@ public class MusicGameActivityHandler extends ActivityHandler { return newRecord.getMaxScore() > saveRecord.getMaxScore(); } public void setMusicGameCustomBeatmapRecord(PlayerActivityData playerActivityData, MusicGamePlayerData.CustomBeatmapRecord newRecord){ - var musicGamePlayerData = getMusicGameRecord(playerActivityData); + var musicGamePlayerData = getMusicGamePlayerData(playerActivityData); musicGamePlayerData.getOthersCustomBeatmapRecord().put(newRecord.getMusicShareId(), newRecord); playerActivityData.setDetail(musicGamePlayerData); @@ -73,7 +73,7 @@ public class MusicGameActivityHandler extends ActivityHandler { } public void addPersonalBeatmap(PlayerActivityData playerActivityData, MusicGameBeatmap musicGameBeatmap) { - var musicGamePlayerData = getMusicGameRecord(playerActivityData); + var musicGamePlayerData = getMusicGamePlayerData(playerActivityData); musicGamePlayerData.getPersonalCustomBeatmapRecord().put(musicGameBeatmap.getMusicShareId(), MusicGamePlayerData.CustomBeatmapRecord.of() .musicShareId(musicGameBeatmap.getMusicShareId()) @@ -82,4 +82,12 @@ public class MusicGameActivityHandler extends ActivityHandler { playerActivityData.setDetail(musicGamePlayerData); playerActivityData.save(); } + + public void removePersonalBeatmap(PlayerActivityData playerActivityData, MusicGameBeatmap musicGameBeatmap) { + var musicGamePlayerData = getMusicGamePlayerData(playerActivityData); + musicGamePlayerData.getPersonalCustomBeatmapRecord().remove(musicGameBeatmap.getMusicShareId()); + + playerActivityData.setDetail(musicGamePlayerData); + playerActivityData.save(); + } } diff --git a/src/main/java/emu/grasscutter/game/activity/musicgame/MusicGameBeatmap.java b/src/main/java/emu/grasscutter/game/activity/musicgame/MusicGameBeatmap.java index 0a5baaf39..1d61433fb 100644 --- a/src/main/java/emu/grasscutter/game/activity/musicgame/MusicGameBeatmap.java +++ b/src/main/java/emu/grasscutter/game/activity/musicgame/MusicGameBeatmap.java @@ -64,12 +64,10 @@ public class MusicGameBeatmap { var player = DatabaseHelper.getPlayerByUid(authorUid); return MusicBriefInfoOuterClass.MusicBriefInfo.newBuilder() - .setCanShare(true) .setMusicId(musicId) .setMusicNoteCount(musicNoteCount) .setMusicShareId(musicShareId) .setMaxScore(maxScore) - .setCreateTime(createTime) .setShareTime(createTime) .setAuthorNickname(player.getNickname()) .setVersion(1) diff --git a/src/main/java/emu/grasscutter/game/activity/musicgame/MusicGamePlayerData.java b/src/main/java/emu/grasscutter/game/activity/musicgame/MusicGamePlayerData.java index 1492d93f9..9b1b97197 100644 --- a/src/main/java/emu/grasscutter/game/activity/musicgame/MusicGamePlayerData.java +++ b/src/main/java/emu/grasscutter/game/activity/musicgame/MusicGamePlayerData.java @@ -61,7 +61,21 @@ public class MusicGamePlayerData { int score; boolean settle; - public MusicBriefInfoOuterClass.MusicBriefInfo.Builder toProto(){ + public MusicBriefInfoOuterClass.MusicBriefInfo.Builder toPersonalBriefProto(){ + var musicGameBeatmap = MusicGameBeatmap.getByShareId(musicShareId); + + return MusicBriefInfoOuterClass.MusicBriefInfo.newBuilder() + .setCanShare(true) + .setCreateTime(musicGameBeatmap.getCreateTime()) + .setMusicId(musicGameBeatmap.getMusicId()) + .setMaxScore(musicGameBeatmap.getMaxScore()) + .setPosition(musicGameBeatmap.getSavePosition()) + .setMusicNoteCount(musicGameBeatmap.getMusicNoteCount()) + .setMusicShareId(musicShareId) + ; + } + + public MusicBriefInfoOuterClass.MusicBriefInfo.Builder toOthersBriefProto(){ var musicGameBeatmap = MusicGameBeatmap.getByShareId(musicShareId); return musicGameBeatmap.toBriefProto() diff --git a/src/main/java/emu/grasscutter/net/packet/PacketOpcodes.java b/src/main/java/emu/grasscutter/net/packet/PacketOpcodes.java index 9582b6fe0..1ea2a46fa 100644 --- a/src/main/java/emu/grasscutter/net/packet/PacketOpcodes.java +++ b/src/main/java/emu/grasscutter/net/packet/PacketOpcodes.java @@ -909,6 +909,8 @@ public class PacketOpcodes { public static final int MusicGameSettleRsp = 8288; public static final int MusicGameStartReq = 8927; public static final int MusicGameStartRsp = 8101; + public static final int MusicGameStartToPlayOthersBeatmapReq = 6302; + public static final int MusicGameStartToPlayOthersBeatmapRsp = 6313; public static final int NavMeshStatsNotify = 2387; public static final int NormalUidOpNotify = 5718; public static final int NpcTalkReq = 509; diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerMusicGameCreateBeatmapReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerMusicGameCreateBeatmapReq.java index b3ac7ef84..e81410213 100644 --- a/src/main/java/emu/grasscutter/server/packet/recv/HandlerMusicGameCreateBeatmapReq.java +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerMusicGameCreateBeatmapReq.java @@ -1,7 +1,9 @@ package emu.grasscutter.server.packet.recv; +import emu.grasscutter.database.DatabaseHelper; import emu.grasscutter.game.activity.musicgame.MusicGameActivityHandler; import emu.grasscutter.game.activity.musicgame.MusicGameBeatmap; +import emu.grasscutter.game.activity.musicgame.MusicGamePlayerData; import emu.grasscutter.game.props.ActivityType; import emu.grasscutter.net.packet.Opcodes; import emu.grasscutter.net.packet.PacketHandler; @@ -12,6 +14,8 @@ import emu.grasscutter.server.packet.send.PacketActivityInfoNotify; import emu.grasscutter.server.packet.send.PacketMusicGameCreateBeatmapRsp; import emu.grasscutter.utils.Utils; +import java.util.Objects; + @Opcodes(PacketOpcodes.MusicGameCreateBeatmapReq) public class HandlerMusicGameCreateBeatmapReq extends PacketHandler { @@ -22,14 +26,13 @@ public class HandlerMusicGameCreateBeatmapReq extends PacketHandler { var musicGameBeatmap = MusicGameBeatmap.of() .musicId(req.getMusicBriefInfo().getMusicId()) .musicNoteCount(req.getMusicBriefInfo().getMusicNoteCount()) - .savePosition(req.getMusicBriefInfo().getSavePosition()) + .savePosition(req.getMusicBriefInfo().getPosition()) .maxScore(req.getMusicBriefInfo().getMaxScore()) .authorUid(session.getPlayer().getUid()) .beatmap(MusicGameBeatmap.parse(req.getMusicRecord().getBeatmapItemListList())) .createTime(Utils.getCurrentSeconds()) .build(); - // TODO avoid player save too much to make server down musicGameBeatmap.save(); var playerData = session.getPlayer().getActivityManager().getPlayerActivityDataByActivityType(ActivityType.NEW_ACTIVITY_MUSIC_GAME); @@ -38,6 +41,22 @@ public class HandlerMusicGameCreateBeatmapReq extends PacketHandler { } var handler = (MusicGameActivityHandler) playerData.get().getActivityHandler(); + var musicGamePlayerData = handler.getMusicGamePlayerData(playerData.get()); + + var oldBeatmap = musicGamePlayerData.getPersonalCustomBeatmapRecord().values().stream() + .map(MusicGamePlayerData.CustomBeatmapRecord::getMusicShareId) + .map(DatabaseHelper::getMusicGameBeatmap) + .filter(Objects::nonNull) + .filter(item -> item.getAuthorUid() == session.getPlayer().getUid()) + .filter(item -> item.getMusicId() == req.getMusicBriefInfo().getMusicId()) + .filter(item -> item.getSavePosition() == req.getMusicBriefInfo().getPosition()) + .findFirst(); + + // delete old beatmap for player + // the old beatmap is still in database so that others can still play. + oldBeatmap.ifPresent(i -> handler.removePersonalBeatmap(playerData.get(), i)); + + // link this beatmap to player's personal data handler.addPersonalBeatmap(playerData.get(), musicGameBeatmap); session.send(new PacketActivityInfoNotify(handler.toProto(playerData.get()))); diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerMusicGameStartToPlayOthersBeatmapReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerMusicGameStartToPlayOthersBeatmapReq.java new file mode 100644 index 000000000..ecdcdd539 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerMusicGameStartToPlayOthersBeatmapReq.java @@ -0,0 +1,20 @@ +package emu.grasscutter.server.packet.recv; + +import emu.grasscutter.net.packet.Opcodes; +import emu.grasscutter.net.packet.PacketHandler; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.proto.MusicGameStartToPlayOthersBeatmapReqOuterClass; +import emu.grasscutter.server.game.GameSession; +import emu.grasscutter.server.packet.send.PacketMusicGameStartToPlayOthersBeatmapRsp; + +@Opcodes(PacketOpcodes.MusicGameStartToPlayOthersBeatmapReq) +public class HandlerMusicGameStartToPlayOthersBeatmapReq extends PacketHandler { + + @Override + public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { + var req = MusicGameStartToPlayOthersBeatmapReqOuterClass.MusicGameStartToPlayOthersBeatmapReq.parseFrom(payload); + + session.send(new PacketMusicGameStartToPlayOthersBeatmapRsp(req.getUnknownEnum1())); + } + +} diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketMusicGameStartToPlayOthersBeatmapRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketMusicGameStartToPlayOthersBeatmapRsp.java new file mode 100644 index 000000000..080a1b84a --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketMusicGameStartToPlayOthersBeatmapRsp.java @@ -0,0 +1,19 @@ +package emu.grasscutter.server.packet.send; + +import emu.grasscutter.net.packet.BasePacket; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.proto.MusicGameStartToPlayOthersBeatmapRspOuterClass; +import emu.grasscutter.net.proto.MusicGameUnknown1EnumOuterClass; + +public class PacketMusicGameStartToPlayOthersBeatmapRsp extends BasePacket { + + public PacketMusicGameStartToPlayOthersBeatmapRsp(MusicGameUnknown1EnumOuterClass.MusicGameUnknown1Enum unknownEnum1) { + super(PacketOpcodes.MusicGameStartToPlayOthersBeatmapRsp); + + var proto = MusicGameStartToPlayOthersBeatmapRspOuterClass.MusicGameStartToPlayOthersBeatmapRsp.newBuilder(); + + proto.setUnknownEnum1(unknownEnum1); + + this.setData(proto); + } +}