diff --git a/proto/ActivityInfo.proto b/proto/ActivityInfo.proto index 6c60d4a47..069c3933e 100755 --- a/proto/ActivityInfo.proto +++ b/proto/ActivityInfo.proto @@ -36,6 +36,7 @@ import "SumoActivityDetailInfo.proto"; import "TreasureMapActivityDetailInfo.proto"; import "TrialAvatarActivityDetailInfo.proto"; import "WaterSpiritActivityDetailInfo.proto";*/ +import "MusicGameActivityDetailInfo.proto"; message ActivityInfo { uint32 activity_id = 1; @@ -59,54 +60,54 @@ message ActivityInfo { //bool MIFCLBCMKJI = 28; //bool BPGCBIEDEDM = 29; //map AGKPABKOHDA = 30; - /*oneof detail { - SeaLampActivityDetailInfo sam_lamp_info = 11; - CrucibleActivityDetailInfo crucible_info = 12; - SalesmanActivityDetailInfo salesman_info = 13; - TrialAvatarActivityDetailInfo trial_avatar_info = 14; - DeliveryActivityDetailInfo delivery_info = 16; - AsterActivityDetailInfo aster_info = 21; - FlightActivityDetailInfo flight_info = 25; - DragonSpineActivityDetailInfo dragon_spine_info = 31; - EffigyActivityDetailInfo effigy_info = 32; - TreasureMapActivityDetailInfo treasure_map_info = 35; - BlessingActivityDetailInfo blessing_info = 41; - SeaLampActivityInfo sea_lamp_info = 42; - ExpeditionActivityDetailInfo expedition_info = 43; - ArenaChallengeActivityDetailInfo arena_challenge_info = 44; - FleurFairActivityDetailInfo fleur_fair_info = 51; - WaterSpiritActivityDetailInfo water_spirit_info = 52; - ChannelerSlabActivityDetailInfo challneler_slab_info = 61; - MistTrialActivityDetailInfo mist_trial_activity_info = 62; - HideAndSeekActivityDetailInfo hide_and_seek_info = 63; - FindHilichurlDetailInfo find_hilichurl_info = 64; - SummerTimeDetailInfo summer_time_info = 65; - BuoyantCombatDetailInfo buoyant_combat_info = 66; - EchoShellDetailInfo echo_shell_info = 67; - BounceConjuringActivityDetailInfo bounce_conjuring_info = 68; - BlitzRushActivityDetailInfo blitz_rush_info = 69; - ChessActivityDetailInfo chess_info = 70; - SumoActivityDetailInfo sumo_info = 71; - MoonfinTrialActivityDetailInfo moonfin_trial_info = 72; - LunaRiteDetailInfo luna_rite_info = 73; - PlantFlowerActivityDetailInfo plant_flower_info = 74; + oneof detail { +// SeaLampActivityDetailInfo sam_lamp_info = 11; +// CrucibleActivityDetailInfo crucible_info = 12; +// SalesmanActivityDetailInfo salesman_info = 13; +// TrialAvatarActivityDetailInfo trial_avatar_info = 14; +// DeliveryActivityDetailInfo delivery_info = 16; +// AsterActivityDetailInfo aster_info = 21; +// FlightActivityDetailInfo flight_info = 25; +// DragonSpineActivityDetailInfo dragon_spine_info = 31; +// EffigyActivityDetailInfo effigy_info = 32; +// TreasureMapActivityDetailInfo treasure_map_info = 35; +// BlessingActivityDetailInfo blessing_info = 41; +// SeaLampActivityInfo sea_lamp_info = 42; +// ExpeditionActivityDetailInfo expedition_info = 43; +// ArenaChallengeActivityDetailInfo arena_challenge_info = 44; +// FleurFairActivityDetailInfo fleur_fair_info = 51; +// WaterSpiritActivityDetailInfo water_spirit_info = 52; +// ChannelerSlabActivityDetailInfo challneler_slab_info = 61; +// MistTrialActivityDetailInfo mist_trial_activity_info = 62; +// HideAndSeekActivityDetailInfo hide_and_seek_info = 63; +// FindHilichurlDetailInfo find_hilichurl_info = 64; +// SummerTimeDetailInfo summer_time_info = 65; +// BuoyantCombatDetailInfo buoyant_combat_info = 66; +// EchoShellDetailInfo echo_shell_info = 67; +// BounceConjuringActivityDetailInfo bounce_conjuring_info = 68; +// BlitzRushActivityDetailInfo blitz_rush_info = 69; +// ChessActivityDetailInfo chess_info = 70; +// SumoActivityDetailInfo sumo_info = 71; +// MoonfinTrialActivityDetailInfo moonfin_trial_info = 72; +// LunaRiteDetailInfo luna_rite_info = 73; +// PlantFlowerActivityDetailInfo plant_flower_info = 74; MusicGameActivityDetailInfo music_game_info = 75; - RoguelikeDungeonActivityDetailInfo roguelike_dungoen_info = 76; - DigActivityDetailInfo dig_info = 77; - DOCNGBMKEID hachi_info = 78; - DLHPBNNDGFI winter_camp_info = 79; - IFACCKLEJCC potion_info = 80; - PFMCPMIMGLM tanuki_travel_activity_info = 81; - JEIAODKGIBD lantern_rite_activity_info = 82; - EPDOGGKOCAP michiae_matsuri_info = 83; - NHMFHLIGAKL bartender_info = 84; - EAGKNMCLJDI ugc_info = 85; - ADPBMLFDHJD crystal_link_info = 86; - JACDNLEIDOO irodori_info = 87; - EHDKFDJEEGP photo_info = 88; - BEPFLAKHNHL spice_info = 89; - MMNEJBFMAEA gacha_info = 90; - JLMHDDHOGGD luminance_stone_challenge_info = 91; - IGBMCJOPGIL rogue_diary_info = 92; - }*/ +// RoguelikeDungeonActivityDetailInfo roguelike_dungoen_info = 76; +// DigActivityDetailInfo dig_info = 77; +// DOCNGBMKEID hachi_info = 78; +// DLHPBNNDGFI winter_camp_info = 79; +// IFACCKLEJCC potion_info = 80; +// PFMCPMIMGLM tanuki_travel_activity_info = 81; +// JEIAODKGIBD lantern_rite_activity_info = 82; +// EPDOGGKOCAP michiae_matsuri_info = 83; +// NHMFHLIGAKL bartender_info = 84; +// EAGKNMCLJDI ugc_info = 85; +// ADPBMLFDHJD crystal_link_info = 86; +// JACDNLEIDOO irodori_info = 87; +// EHDKFDJEEGP photo_info = 88; +// BEPFLAKHNHL spice_info = 89; +// MMNEJBFMAEA gacha_info = 90; +// JLMHDDHOGGD luminance_stone_challenge_info = 91; +// IGBMCJOPGIL rogue_diary_info = 92; + } } diff --git a/proto/MusicBeatmap.proto b/proto/MusicBeatmap.proto new file mode 100644 index 000000000..48da4526e --- /dev/null +++ b/proto/MusicBeatmap.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +option java_package = "emu.grasscutter.net.proto"; + +import "MusicBeatmapList.proto"; + +message MusicBeatmap { + uint32 music_id = 1; + repeated MusicBeatmapList beatmap_item_list = 2; +} diff --git a/proto/MusicBeatmapList.proto b/proto/MusicBeatmapList.proto new file mode 100644 index 000000000..5da8e21a7 --- /dev/null +++ b/proto/MusicBeatmapList.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +option java_package = "emu.grasscutter.net.proto"; + +import "MusicBeatmapNote.proto"; + +message MusicBeatmapList { + repeated MusicBeatmapNote beatmap_note_list = 1; +} diff --git a/proto/MusicBeatmapNote.proto b/proto/MusicBeatmapNote.proto new file mode 100644 index 000000000..d83fe0a92 --- /dev/null +++ b/proto/MusicBeatmapNote.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +option java_package = "emu.grasscutter.net.proto"; + +message MusicBeatmapNote { + uint32 start_time = 1; + uint32 end_time = 2; +} diff --git a/proto/MusicBriefInfo.proto b/proto/MusicBriefInfo.proto new file mode 100644 index 000000000..6b9ae2878 --- /dev/null +++ b/proto/MusicBriefInfo.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; + +option java_package = "emu.grasscutter.net.proto"; + +message MusicBriefInfo { + uint64 music_share_id = 1; + uint32 music_id = 2; + string author_nickname = 3; + uint32 music_note_count = 4; + uint32 max_score = 5; + uint32 score = 6; + uint32 create_time = 7; + uint32 share_time = 8; + uint32 DOANBAODBMA = 9; + bool settle = 10; + uint32 version = 11; + bool can_share = 12; + bool OAPKHNELBPH = 13; + bool NJHAMJMHPAA = 14; + uint64 ADIBIKKNPKK = 15; + uint32 save_position = 21; + repeated uint32 GIDFMAJFIFE = 22; + repeated uint32 OKBJPAKOLIH = 23; + uint32 FAOPBAMDFJB = 24; + uint32 FELMANEFAOE = 25; +} diff --git a/proto/MusicGameActivityDetailInfo.proto b/proto/MusicGameActivityDetailInfo.proto index 168a1848a..1d38dd8e9 100644 --- a/proto/MusicGameActivityDetailInfo.proto +++ b/proto/MusicGameActivityDetailInfo.proto @@ -2,11 +2,11 @@ syntax = "proto3"; option java_package = "emu.grasscutter.net.proto"; -//import "MusicBriefInfo.proto"; -//import "MusicGameRecord.proto"; -// -//message MusicGameActivityDetailInfo { -// map music_game_record_map = 1; -// repeated MusicBriefInfo LGNAAPPDLGG = 2; -// repeated MusicBriefInfo HHHIDFPPPFK = 3; -//} +import "MusicBriefInfo.proto"; +import "MusicGameRecord.proto"; + +message MusicGameActivityDetailInfo { + map music_game_record_map = 1; + repeated MusicBriefInfo person_custom_beatmap = 2; + repeated MusicBriefInfo others_custom_beatmap = 3; +} diff --git a/proto/MusicGameCreateBeatmapReq.proto b/proto/MusicGameCreateBeatmapReq.proto new file mode 100644 index 000000000..a2274d130 --- /dev/null +++ b/proto/MusicGameCreateBeatmapReq.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +option java_package = "emu.grasscutter.net.proto"; + +import "MusicBeatmap.proto"; +import "MusicBriefInfo.proto"; +import "MusicGameUnknown1Enum.proto"; + +// CmdId: 6326 +// EnetChannelId: 0 +// EnetIsReliable: true +// IsAllowClient: true +message MusicGameCreateBeatmapReq { + MusicGameUnknown1Enum unknown_enum1 = 12; + oneof beatmap { + MusicBeatmap music_record = 10; + } + oneof brief_info { + MusicBriefInfo music_brief_info = 1021; + } +} diff --git a/proto/MusicGameCreateBeatmapRsp.proto b/proto/MusicGameCreateBeatmapRsp.proto new file mode 100644 index 000000000..66ce2f582 --- /dev/null +++ b/proto/MusicGameCreateBeatmapRsp.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +option java_package = "emu.grasscutter.net.proto"; + +import "MusicGameUnknown1Enum.proto"; + +// CmdId: 6347 +// EnetChannelId: 0 +// EnetIsReliable: true + +message MusicGameCreateBeatmapRsp { + int32 retcode = 10; + MusicGameUnknown1Enum unknown_enum1 = 12; + uint64 music_share_id = 5; +} diff --git a/proto/MusicGameGetBeatmapReq.proto b/proto/MusicGameGetBeatmapReq.proto new file mode 100644 index 000000000..2946ffd07 --- /dev/null +++ b/proto/MusicGameGetBeatmapReq.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + +option java_package = "emu.grasscutter.net.proto"; + +import "MusicGameUnknown2Enum.proto"; +import "MusicGameGetBeatmapReqType.proto"; +import "MusicGameUnknown1Enum.proto"; + +// CmdId: 6318 +// EnetChannelId: 0 +// EnetIsReliable: true +// IsAllowClient: true +message MusicGameGetBeatmapReq { + MusicGameUnknown1Enum unknown_enum1 = 1; + uint64 music_share_id = 10; + MusicGameUnknown2Enum unknown_enum2 = 12; + bool CDFOGGDLKNA = 15; + MusicGameGetBeatmapReqType req_type = 11; +} diff --git a/proto/MusicGameGetBeatmapReqType.proto b/proto/MusicGameGetBeatmapReqType.proto new file mode 100644 index 000000000..63935da16 --- /dev/null +++ b/proto/MusicGameGetBeatmapReqType.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +option java_package = "emu.grasscutter.net.proto"; + +enum MusicGameGetBeatmapReqType { + MusicGameGetBeatmapReqType_u1 = 0; + // edit_beatmap + MusicGameGetBeatmapReqType_u2 = 1; + // play_others + MusicGameGetBeatmapReqType_u3 = 2; + // try + MusicGameGetBeatmapReqType_u4 = 3; + MusicGameGetBeatmapReqType_u5 = 4; +} diff --git a/proto/MusicGameGetBeatmapRsp.proto b/proto/MusicGameGetBeatmapRsp.proto new file mode 100644 index 000000000..e4174dbaa --- /dev/null +++ b/proto/MusicGameGetBeatmapRsp.proto @@ -0,0 +1,24 @@ +syntax = "proto3"; + +option java_package = "emu.grasscutter.net.proto"; + +import "MusicGameGetBeatmapReqType.proto"; +import "MusicBeatmap.proto"; +import "MusicBriefInfo.proto"; +import "MusicGameUnknown1Enum.proto"; + +// CmdId: 6309 +// EnetChannelId: 0 +// EnetIsReliable: true +message MusicGameGetBeatmapRsp { + int32 retcode = 13; + MusicGameUnknown1Enum unknown_enum1 = 1; + uint64 music_share_id = 5; + MusicGameGetBeatmapReqType req_type = 2; + oneof beatmap { + MusicBeatmap music_record = 9; + } + oneof brief_info { + MusicBriefInfo music_brief_info = 953; + } +} diff --git a/proto/MusicGameRecord.proto b/proto/MusicGameRecord.proto new file mode 100644 index 000000000..6eb29f29d --- /dev/null +++ b/proto/MusicGameRecord.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +option java_package = "emu.grasscutter.net.proto"; + +message MusicGameRecord { + uint32 max_score = 1; + uint32 max_combo = 2; + bool is_unlock = 3; +} diff --git a/proto/MusicGameSearchBeatmapReq.proto b/proto/MusicGameSearchBeatmapReq.proto new file mode 100644 index 000000000..d17e921fc --- /dev/null +++ b/proto/MusicGameSearchBeatmapReq.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +option java_package = "emu.grasscutter.net.proto"; + +import "MusicGameUnknown1Enum.proto"; + +// CmdId: 6343 +// EnetChannelId: 0 +// EnetIsReliable: true +// IsAllowClient: true +message MusicGameSearchBeatmapReq { + MusicGameUnknown1Enum unknown_enum1 = 10; + uint64 music_share_id = 6; +} diff --git a/proto/MusicGameSearchBeatmapRsp.proto b/proto/MusicGameSearchBeatmapRsp.proto new file mode 100644 index 000000000..3ce4ffca0 --- /dev/null +++ b/proto/MusicGameSearchBeatmapRsp.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +option java_package = "emu.grasscutter.net.proto"; + +import "MusicBriefInfo.proto"; +import "MusicGameUnknown1Enum.proto"; + +// CmdId: 6304 +// EnetChannelId: 0 +// EnetIsReliable: true +message MusicGameSearchBeatmapRsp { + int32 retcode = 9; + MusicGameUnknown1Enum unknown_enum1 = 3; + uint64 music_share_id = 4; + oneof ELBEIFGDBMM { + MusicBriefInfo music_brief_info = 11; + } +} diff --git a/proto/MusicGameSettleReq.proto b/proto/MusicGameSettleReq.proto index 11366a1ed..2cb18a08f 100644 --- a/proto/MusicGameSettleReq.proto +++ b/proto/MusicGameSettleReq.proto @@ -11,17 +11,20 @@ message MusicGameSettleReq { uint32 score = 2; uint32 combo = 10; uint32 correct_hit = 8; - uint64 KKONDPNGBJD = 11; + uint64 music_share_id = 11; + // is_default_beatmap bool KJNDJLBOJLM = 4; uint32 FBELCAFFGIJ = 3; uint32 OOFMAKIDFOL = 15; + // beatmap_difficulty_level uint32 HJPDEIMECHB = 1; repeated uint32 MNCMGANHCFI = 13; uint32 max_combo = 9; uint32 JJADNMELLAH = 1975; + // detail_score repeated uint32 EIAGEEFABPO = 1171; uint32 CPIFLFBHNJP = 1104; - bool DJCKOHKLIOB = 998; + bool success = 998; uint32 GGHBOMGJGFP = 268; bool PFHCIHKCJFJ = 238; float speed = 887; diff --git a/proto/MusicGameSettleRsp.proto b/proto/MusicGameSettleRsp.proto index 297232c95..1e8b0dc6f 100644 --- a/proto/MusicGameSettleRsp.proto +++ b/proto/MusicGameSettleRsp.proto @@ -10,5 +10,5 @@ message MusicGameSettleRsp { uint32 music_basic_id = 9; bool is_unlock_next_level = 1; bool is_new_record = 3; - uint64 KKONDPNGBJD = 11; + uint64 music_share_id = 11; } diff --git a/proto/MusicGameStartReq.proto b/proto/MusicGameStartReq.proto index 962c1844e..b0c940e9c 100644 --- a/proto/MusicGameStartReq.proto +++ b/proto/MusicGameStartReq.proto @@ -8,6 +8,6 @@ option java_package = "emu.grasscutter.net.proto"; // IsAllowClient: true message MusicGameStartReq { uint32 music_basic_id = 10; - uint64 KKONDPNGBJD = 8; + uint64 music_share_id = 8; bool KJNDJLBOJLM = 5; } diff --git a/proto/MusicGameStartRsp.proto b/proto/MusicGameStartRsp.proto index fff9b466b..6660eeffd 100644 --- a/proto/MusicGameStartRsp.proto +++ b/proto/MusicGameStartRsp.proto @@ -8,5 +8,5 @@ option java_package = "emu.grasscutter.net.proto"; message MusicGameStartRsp { int32 retcode = 5; uint32 music_basic_id = 14; - uint64 KKONDPNGBJD = 12; + uint64 music_share_id = 12; } diff --git a/proto/MusicGameUnknown1Enum.proto b/proto/MusicGameUnknown1Enum.proto new file mode 100644 index 000000000..ea660c3b6 --- /dev/null +++ b/proto/MusicGameUnknown1Enum.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +option java_package = "emu.grasscutter.net.proto"; + +enum MusicGameUnknown1Enum { + MusicGameUnknown1Enum_NONE = 0; + MusicGameUnknown1Enum_u2 = 1; +} diff --git a/proto/MusicGameUnknown2Enum.proto b/proto/MusicGameUnknown2Enum.proto new file mode 100644 index 000000000..b64a75102 --- /dev/null +++ b/proto/MusicGameUnknown2Enum.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +option java_package = "emu.grasscutter.net.proto"; + +enum MusicGameUnknown2Enum { + MusicGameUnknown2Enum_u1 = 0; + MusicGameUnknown2Enum_MINE = 1; + MusicGameUnknown2Enum_u3 = 2; +} diff --git a/src/main/java/emu/grasscutter/data/GameData.java b/src/main/java/emu/grasscutter/data/GameData.java index 780564cbd..da95b1bcc 100644 --- a/src/main/java/emu/grasscutter/data/GameData.java +++ b/src/main/java/emu/grasscutter/data/GameData.java @@ -101,6 +101,7 @@ public class GameData { @Getter private static final Int2ObjectMap activityDataMap = new Int2ObjectOpenHashMap<>(); @Getter private static final Int2ObjectMap activityWatcherDataMap = new Int2ObjectOpenHashMap<>(); + @Getter private static final Int2ObjectMap musicGameBasicDataMap = new Int2ObjectOpenHashMap<>(); // Cache private static Map> fetters = new HashMap<>(); diff --git a/src/main/java/emu/grasscutter/data/excels/ActivityWatcherData.java b/src/main/java/emu/grasscutter/data/excels/ActivityWatcherData.java index e784693f9..4ff176fa5 100644 --- a/src/main/java/emu/grasscutter/data/excels/ActivityWatcherData.java +++ b/src/main/java/emu/grasscutter/data/excels/ActivityWatcherData.java @@ -2,6 +2,7 @@ package emu.grasscutter.data.excels; import emu.grasscutter.data.GameResource; import emu.grasscutter.data.ResourceType; +import emu.grasscutter.game.props.WatcherTriggerType; import lombok.AccessLevel; import lombok.Getter; import lombok.experimental.FieldDefaults; @@ -24,6 +25,7 @@ public class ActivityWatcherData extends GameResource { @Override public void onLoad() { triggerConfig.paramList = triggerConfig.paramList.stream().filter(x -> !x.isBlank()).toList(); + triggerConfig.watcherTriggerType = WatcherTriggerType.getTypeByName(triggerConfig.triggerType); } @Getter @@ -31,6 +33,8 @@ public class ActivityWatcherData extends GameResource { public static class WatcherTrigger{ String triggerType; List paramList; + + transient WatcherTriggerType watcherTriggerType; } } diff --git a/src/main/java/emu/grasscutter/data/excels/MusicGameBasicData.java b/src/main/java/emu/grasscutter/data/excels/MusicGameBasicData.java new file mode 100644 index 000000000..d73d74ce9 --- /dev/null +++ b/src/main/java/emu/grasscutter/data/excels/MusicGameBasicData.java @@ -0,0 +1,21 @@ +package emu.grasscutter.data.excels; + +import emu.grasscutter.data.GameResource; +import emu.grasscutter.data.ResourceType; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.experimental.FieldDefaults; + +@ResourceType(name = "MusicGameBasicConfigData.json") +@Getter +@FieldDefaults(level = AccessLevel.PRIVATE) +public class MusicGameBasicData extends GameResource { + int id; + int musicID; + int musicLevel; + + @Override + public int getId() { + return this.id; + } +} diff --git a/src/main/java/emu/grasscutter/database/DatabaseHelper.java b/src/main/java/emu/grasscutter/database/DatabaseHelper.java index 55afc4354..1178ddc47 100644 --- a/src/main/java/emu/grasscutter/database/DatabaseHelper.java +++ b/src/main/java/emu/grasscutter/database/DatabaseHelper.java @@ -11,6 +11,7 @@ import emu.grasscutter.GameConstants; import emu.grasscutter.Grasscutter; import emu.grasscutter.game.Account; import emu.grasscutter.game.activity.PlayerActivityData; +import emu.grasscutter.game.activity.musicgame.MusicGameBeatmap; import emu.grasscutter.game.avatar.Avatar; import emu.grasscutter.game.battlepass.BattlePassManager; import emu.grasscutter.game.friends.Friendship; @@ -337,4 +338,13 @@ public final class DatabaseHelper { public static void savePlayerActivityData(PlayerActivityData playerActivityData) { DatabaseManager.getGameDatastore().save(playerActivityData); } + public static MusicGameBeatmap getMusicGameBeatmap(long musicShareId) { + return DatabaseManager.getGameDatastore().find(MusicGameBeatmap.class) + .filter(Filters.eq("musicShareId", musicShareId)) + .first(); + } + + public static void saveMusicGameBeatmap(MusicGameBeatmap musicGameBeatmap) { + DatabaseManager.getGameDatastore().save(musicGameBeatmap); + } } diff --git a/src/main/java/emu/grasscutter/database/DatabaseManager.java b/src/main/java/emu/grasscutter/database/DatabaseManager.java index 19618c27b..d0c322864 100644 --- a/src/main/java/emu/grasscutter/database/DatabaseManager.java +++ b/src/main/java/emu/grasscutter/database/DatabaseManager.java @@ -14,6 +14,7 @@ import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter.ServerRunMode; import emu.grasscutter.game.Account; import emu.grasscutter.game.activity.PlayerActivityData; +import emu.grasscutter.game.activity.musicgame.MusicGameBeatmap; import emu.grasscutter.game.avatar.Avatar; import emu.grasscutter.game.battlepass.BattlePassManager; import emu.grasscutter.game.friends.Friendship; @@ -33,12 +34,14 @@ public final class DatabaseManager { private static final Class[] mappedClasses = new Class[] { DatabaseCounter.class, Account.class, Player.class, Avatar.class, GameItem.class, Friendship.class, - GachaRecord.class, Mail.class, GameMainQuest.class, GameHome.class, BattlePassManager.class, PlayerActivityData.class + GachaRecord.class, Mail.class, GameMainQuest.class, GameHome.class, BattlePassManager.class, + PlayerActivityData.class, MusicGameBeatmap.class }; + public static Datastore getGameDatastore() { return gameDatastore; } - + public static MongoDatabase getGameDatabase() { return getGameDatastore().getDatabase(); } diff --git a/src/main/java/emu/grasscutter/game/activity/ActivityHandler.java b/src/main/java/emu/grasscutter/game/activity/ActivityHandler.java index 386533d5c..5a8709cd6 100644 --- a/src/main/java/emu/grasscutter/game/activity/ActivityHandler.java +++ b/src/main/java/emu/grasscutter/game/activity/ActivityHandler.java @@ -26,12 +26,15 @@ public abstract class ActivityHandler { ActivityData activityData; Map> watchersMap = new HashMap<>(); - public void initWatchers(HashMap> activityWatcherTypeMap){ + abstract public void onProtoBuild(PlayerActivityData playerActivityData, ActivityInfoOuterClass.ActivityInfo.Builder activityInfo); + abstract public void onInitPlayerActivityData(PlayerActivityData playerActivityData); + + public void initWatchers(Map> activityWatcherTypeMap){ activityData = GameData.getActivityDataMap().get(activityConfigItem.getActivityId()); // add watcher to map by id activityData.getWatcherDataList().forEach(watcherData -> { - var watcherType = activityWatcherTypeMap.get(watcherData.getTriggerConfig().getTriggerType()); + var watcherType = activityWatcherTypeMap.get(watcherData.getTriggerConfig().getWatcherTriggerType()); ActivityWatcher watcher; if(watcherType != null){ watcher = (ActivityWatcher) watcherType.newInstance(); @@ -42,8 +45,8 @@ public abstract class ActivityHandler { watcher.setWatcherId(watcherData.getId()); watcher.setActivityHandler(this); watcher.setActivityWatcherData(watcherData); - watchersMap.computeIfAbsent(WatcherTriggerType.getTypeByName(watcherData.getTriggerConfig().getTriggerType()), k -> new ArrayList<>()); - watchersMap.get(WatcherTriggerType.getTypeByName(watcherData.getTriggerConfig().getTriggerType())).add(watcher); + watchersMap.computeIfAbsent(watcherData.getTriggerConfig().getWatcherTriggerType(), k -> new ArrayList<>()); + watchersMap.get(watcherData.getTriggerConfig().getWatcherTriggerType()).add(watcher); }); } @@ -55,16 +58,19 @@ public abstract class ActivityHandler { } public PlayerActivityData initPlayerActivityData(Player player){ - return PlayerActivityData.of() + PlayerActivityData playerActivityData = PlayerActivityData.of() .activityId(activityConfigItem.getActivityId()) .uid(player.getUid()) .watcherInfoMap(initWatchersDataForPlayer()) .build(); + + onInitPlayerActivityData(playerActivityData); + return playerActivityData; } - - public void buildProto(PlayerActivityData playerActivityData, ActivityInfoOuterClass.ActivityInfo.Builder activityInfo){ - activityInfo.setActivityId(activityConfigItem.getActivityId()) + public ActivityInfoOuterClass.ActivityInfo toProto(PlayerActivityData playerActivityData){ + var proto = ActivityInfoOuterClass.ActivityInfo.newBuilder(); + proto.setActivityId(activityConfigItem.getActivityId()) .setActivityType(activityConfigItem.getActivityType()) .setScheduleId(activityConfigItem.getScheduleId()) .setBeginTime(DateHelper.getUnixTime(activityConfigItem.getBeginTime())) @@ -73,9 +79,12 @@ public abstract class ActivityHandler { .addAllMeetCondList(activityConfigItem.getMeetCondList()); if (playerActivityData != null){ - activityInfo.addAllWatcherInfoList(playerActivityData.getAllWatcherInfoList()); + proto.addAllWatcherInfoList(playerActivityData.getAllWatcherInfoList()); } + onProtoBuild(playerActivityData, proto); + + return proto.build(); } } diff --git a/src/main/java/emu/grasscutter/game/activity/ActivityManager.java b/src/main/java/emu/grasscutter/game/activity/ActivityManager.java index b8b4db168..b511a2629 100644 --- a/src/main/java/emu/grasscutter/game/activity/ActivityManager.java +++ b/src/main/java/emu/grasscutter/game/activity/ActivityManager.java @@ -6,6 +6,7 @@ import emu.grasscutter.Grasscutter; import emu.grasscutter.data.DataLoader; import emu.grasscutter.data.GameData; import emu.grasscutter.game.player.Player; +import emu.grasscutter.game.props.ActivityType; import emu.grasscutter.game.props.WatcherTriggerType; import emu.grasscutter.net.proto.ActivityInfoOuterClass; import emu.grasscutter.server.packet.send.PacketActivityScheduleInfoNotify; @@ -25,41 +26,22 @@ public class ActivityManager { static { activityConfigItemMap = new HashMap<>(); - loadActivityConfigData(); } - public ActivityManager(Player player){ - this.player = player; - - playerActivityDataMap = new ConcurrentHashMap<>(); - // load data for player - activityConfigItemMap.values().forEach(item -> { - var data = PlayerActivityData.getByPlayer(player, item.getActivityId()); - if(data == null){ - data = item.getActivityHandler().initPlayerActivityData(player); - data.save(); - } - data.setPlayer(player); - playerActivityDataMap.put(item.getActivityId(), data); - }); - - player.sendPacket(new PacketActivityScheduleInfoNotify(activityConfigItemMap.values())); - } - private static void loadActivityConfigData() { // scan activity type handler & watcher type - var activityHandlerTypeMap = new HashMap>(); - var activityWatcherTypeMap = new HashMap>(); + var activityHandlerTypeMap = new HashMap>(); + var activityWatcherTypeMap = new HashMap>(); var reflections = new Reflections(ActivityManager.class.getPackage().getName()); reflections.getSubTypesOf(ActivityHandler.class).forEach(item -> { - var typeName = item.getAnnotation(ActivityType.class); + var typeName = item.getAnnotation(GameActivity.class); activityHandlerTypeMap.put(typeName.value(), ConstructorAccess.get(item)); }); reflections.getSubTypesOf(ActivityWatcher.class).forEach(item -> { - var typeName = item.getAnnotation(WatcherType.class); - activityWatcherTypeMap.put(typeName.value().name(), ConstructorAccess.get(item)); + var typeName = item.getAnnotation(ActivityWatcherType.class); + activityWatcherTypeMap.put(typeName.value(), ConstructorAccess.get(item)); }); try(InputStream is = DataLoader.load("ActivityConfig.json"); InputStreamReader isr = new InputStreamReader(is)) { @@ -74,39 +56,49 @@ public class ActivityManager { Grasscutter.getLogger().warn("activity {} not exist.", item.getActivityId()); return; } - var activityHandlerType = activityHandlerTypeMap.get(activityData.getActivityType()); + var activityHandlerType = activityHandlerTypeMap.get(ActivityType.getTypeByName(activityData.getActivityType())); + ActivityHandler activityHandler; if(activityHandlerType != null) { - var activityHandler = (ActivityHandler) activityHandlerType.newInstance(); - activityHandler.setActivityConfigItem(item); - activityHandler.initWatchers(activityWatcherTypeMap); - item.setActivityHandler(activityHandler); + activityHandler = (ActivityHandler) activityHandlerType.newInstance(); + }else{ + activityHandler = new DefaultActivityHandler(); } + activityHandler.setActivityConfigItem(item); + activityHandler.initWatchers(activityWatcherTypeMap); + item.setActivityHandler(activityHandler); activityConfigItemMap.putIfAbsent(item.getActivityId(), item); }); - Grasscutter.getLogger().error("Enable {} activities.", activityConfigItemMap.size()); + Grasscutter.getLogger().info("Enable {} activities.", activityConfigItemMap.size()); } catch (Exception e) { - Grasscutter.getLogger().error("Unable to load chest reward config.", e); + Grasscutter.getLogger().error("Unable to load activities config.", e); } } - public ActivityInfoOuterClass.ActivityInfo getInfoProto(int activityId){ - var activityHandler = activityConfigItemMap.get(activityId).getActivityHandler(); - var activityData = playerActivityDataMap.get(activityId); + public ActivityManager(Player player){ + this.player = player; - var proto = ActivityInfoOuterClass.ActivityInfo.newBuilder(); - activityHandler.buildProto(activityData, proto); + playerActivityDataMap = new ConcurrentHashMap<>(); + // load data for player + activityConfigItemMap.values().forEach(item -> { + var data = PlayerActivityData.getByPlayer(player, item.getActivityId()); + if(data == null){ + data = item.getActivityHandler().initPlayerActivityData(player); + data.save(); + } + data.setPlayer(player); + data.setActivityHandler(item.getActivityHandler()); + playerActivityDataMap.put(item.getActivityId(), data); + }); - return proto.build(); + player.sendPacket(new PacketActivityScheduleInfoNotify(activityConfigItemMap.values())); } /** * trigger activity watcher - * @param watcherTriggerType - * @param params */ public void triggerWatcher(WatcherTriggerType watcherTriggerType, String... params) { var watchers = activityConfigItemMap.values().stream() @@ -122,4 +114,37 @@ public class ActivityManager { playerActivityDataMap.get(watcher.getActivityHandler().getActivityConfigItem().getActivityId()), params)); } + + public ActivityInfoOuterClass.ActivityInfo getInfoProtoByActivityId(int activityId){ + var activityHandler = activityConfigItemMap.get(activityId).getActivityHandler(); + var activityData = playerActivityDataMap.get(activityId); + + return activityHandler.toProto(activityData); + } + + public Optional getActivityHandler(ActivityType type){ + return activityConfigItemMap.values().stream() + .map(ActivityConfigItem::getActivityHandler) + .filter(x -> type == x.getClass().getAnnotation(GameActivity.class).value()) + .findFirst(); + } + + public Optional getActivityHandlerAs(ActivityType type, Class clazz){ + return getActivityHandler(type).map(x -> (T)x); + } + + public Optional getActivityIdByActivityType(ActivityType type){ + return getActivityHandler(type) + .map(ActivityHandler::getActivityConfigItem) + .map(ActivityConfigItem::getActivityId); + } + public Optional getPlayerActivityDataByActivityType(ActivityType type){ + return getActivityIdByActivityType(type) + .map(playerActivityDataMap::get); + } + public Optional getInfoProtoByActivityType(ActivityType type){ + return getActivityIdByActivityType(type) + .map(this::getInfoProtoByActivityId); + } + } diff --git a/src/main/java/emu/grasscutter/game/activity/WatcherType.java b/src/main/java/emu/grasscutter/game/activity/ActivityWatcherType.java similarity index 89% rename from src/main/java/emu/grasscutter/game/activity/WatcherType.java rename to src/main/java/emu/grasscutter/game/activity/ActivityWatcherType.java index 7d1f9a261..4c68e11f5 100644 --- a/src/main/java/emu/grasscutter/game/activity/WatcherType.java +++ b/src/main/java/emu/grasscutter/game/activity/ActivityWatcherType.java @@ -9,6 +9,6 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) -public @interface WatcherType { +public @interface ActivityWatcherType { WatcherTriggerType value(); } diff --git a/src/main/java/emu/grasscutter/game/activity/DefaultActivityHandler.java b/src/main/java/emu/grasscutter/game/activity/DefaultActivityHandler.java new file mode 100644 index 000000000..693878328 --- /dev/null +++ b/src/main/java/emu/grasscutter/game/activity/DefaultActivityHandler.java @@ -0,0 +1,17 @@ +package emu.grasscutter.game.activity; + +import emu.grasscutter.game.props.ActivityType; +import emu.grasscutter.net.proto.ActivityInfoOuterClass; + +@GameActivity(ActivityType.NONE) +public class DefaultActivityHandler extends ActivityHandler{ + @Override + public void onProtoBuild(PlayerActivityData playerActivityData, ActivityInfoOuterClass.ActivityInfo.Builder activityInfo) { + + } + + @Override + public void onInitPlayerActivityData(PlayerActivityData playerActivityData) { + + } +} diff --git a/src/main/java/emu/grasscutter/game/activity/DefaultWatcher.java b/src/main/java/emu/grasscutter/game/activity/DefaultWatcher.java index 8c6e2464f..bd4c93fe6 100644 --- a/src/main/java/emu/grasscutter/game/activity/DefaultWatcher.java +++ b/src/main/java/emu/grasscutter/game/activity/DefaultWatcher.java @@ -2,7 +2,7 @@ package emu.grasscutter.game.activity; import emu.grasscutter.game.props.WatcherTriggerType; -@WatcherType(WatcherTriggerType.TRIGGER_NONE) +@ActivityWatcherType(WatcherTriggerType.TRIGGER_NONE) public class DefaultWatcher extends ActivityWatcher{ @Override protected boolean isMeet(String... param) { diff --git a/src/main/java/emu/grasscutter/game/activity/ActivityType.java b/src/main/java/emu/grasscutter/game/activity/GameActivity.java similarity index 71% rename from src/main/java/emu/grasscutter/game/activity/ActivityType.java rename to src/main/java/emu/grasscutter/game/activity/GameActivity.java index da57637e7..7d70a653d 100644 --- a/src/main/java/emu/grasscutter/game/activity/ActivityType.java +++ b/src/main/java/emu/grasscutter/game/activity/GameActivity.java @@ -1,5 +1,7 @@ package emu.grasscutter.game.activity; +import emu.grasscutter.game.props.ActivityType; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -7,6 +9,6 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) -public @interface ActivityType { - String value(); +public @interface GameActivity { + ActivityType value(); } diff --git a/src/main/java/emu/grasscutter/game/activity/PlayerActivityData.java b/src/main/java/emu/grasscutter/game/activity/PlayerActivityData.java index 4a251a621..3a4b207f3 100644 --- a/src/main/java/emu/grasscutter/game/activity/PlayerActivityData.java +++ b/src/main/java/emu/grasscutter/game/activity/PlayerActivityData.java @@ -3,8 +3,14 @@ package emu.grasscutter.game.activity; import dev.morphia.annotations.Entity; import dev.morphia.annotations.Id; import dev.morphia.annotations.Transient; +import emu.grasscutter.Grasscutter; +import emu.grasscutter.data.GameData; +import emu.grasscutter.data.common.ItemParamData; +import emu.grasscutter.data.excels.ActivityWatcherData; import emu.grasscutter.database.DatabaseHelper; +import emu.grasscutter.game.inventory.GameItem; import emu.grasscutter.game.player.Player; +import emu.grasscutter.game.props.ActionReason; import emu.grasscutter.net.proto.ActivityWatcherInfoOuterClass; import emu.grasscutter.server.packet.send.PacketActivityUpdateWatcherNotify; import lombok.AccessLevel; @@ -12,8 +18,10 @@ import lombok.Builder; import lombok.Data; import lombok.experimental.FieldDefaults; +import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Optional; @Entity("activities") @Data @@ -25,9 +33,12 @@ public class PlayerActivityData { int uid; int activityId; Map watcherInfoMap; + /** + * the detail data of each type of activity (Json format) + */ String detail; @Transient Player player; - + @Transient ActivityHandler activityHandler; public void save(){ DatabaseHelper.savePlayerActivityData(this); } @@ -56,6 +67,35 @@ public class PlayerActivityData { .toList(); } + public void setDetail(Object detail){ + this.detail = Grasscutter.getGsonFactory().toJson(detail); + } + + public void takeWatcherReward(int watcherId) { + var watcher = watcherInfoMap.get(watcherId); + if(watcher == null || watcher.isTakenReward()){ + return; + } + + var reward = Optional.of(watcher) + .map(WatcherInfo::getMetadata) + .map(ActivityWatcherData::getRewardID) + .map(id -> GameData.getRewardDataMap().get(id.intValue())); + + if(reward.isEmpty()){ + return; + } + + List rewards = new ArrayList<>(); + for (ItemParamData param : reward.get().getRewardItemList()) { + rewards.add(new GameItem(param.getId(), Math.max(param.getCount(), 1))); + } + + player.getInventory().addItems(rewards, ActionReason.ActivityWatcher); + watcher.setTakenReward(true); + save(); + } + @Entity @Data @FieldDefaults(level = AccessLevel.PRIVATE) @@ -66,6 +106,10 @@ public class PlayerActivityData { int curProgress; boolean isTakenReward; + public ActivityWatcherData getMetadata(){ + return GameData.getActivityWatcherDataMap().get(watcherId); + } + public static WatcherInfo init(ActivityWatcher watcher){ return WatcherInfo.of() .watcherId(watcher.getWatcherId()) 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 c3d5ad53a..0dcb0ae55 100644 --- a/src/main/java/emu/grasscutter/game/activity/musicgame/MusicGameActivityHandler.java +++ b/src/main/java/emu/grasscutter/game/activity/musicgame/MusicGameActivityHandler.java @@ -1,17 +1,85 @@ package emu.grasscutter.game.activity.musicgame; +import emu.grasscutter.Grasscutter; import emu.grasscutter.game.activity.ActivityHandler; -import emu.grasscutter.game.activity.ActivityType; +import emu.grasscutter.game.activity.GameActivity; import emu.grasscutter.game.activity.PlayerActivityData; +import emu.grasscutter.game.props.ActivityType; import emu.grasscutter.net.proto.ActivityInfoOuterClass; +import emu.grasscutter.net.proto.MusicBriefInfoOuterClass; +import emu.grasscutter.net.proto.MusicGameActivityDetailInfoOuterClass; -@ActivityType("NEW_ACTIVITY_MUSIC_GAME") +import java.util.stream.Collectors; + +@GameActivity(ActivityType.NEW_ACTIVITY_MUSIC_GAME) public class MusicGameActivityHandler extends ActivityHandler { @Override - public void buildProto(PlayerActivityData playerActivityData, ActivityInfoOuterClass.ActivityInfo.Builder activityInfo) { - super.buildProto(playerActivityData, activityInfo); + public void onInitPlayerActivityData(PlayerActivityData playerActivityData) { + var musicGamePlayerData = MusicGamePlayerData.create(); + playerActivityData.setDetail(musicGamePlayerData); + } + @Override + public void onProtoBuild(PlayerActivityData playerActivityData, ActivityInfoOuterClass.ActivityInfo.Builder activityInfo) { + MusicGamePlayerData musicGamePlayerData = getMusicGameRecord(playerActivityData); + + activityInfo.setMusicGameInfo(MusicGameActivityDetailInfoOuterClass.MusicGameActivityDetailInfo.newBuilder() + .putAllMusicGameRecordMap( + musicGamePlayerData.getMusicGameRecord().values().stream() + .collect(Collectors.toMap(MusicGamePlayerData.MusicGameRecord::getMusicId, MusicGamePlayerData.MusicGameRecord::toProto))) + + .addAllPersonCustomBeatmap(musicGamePlayerData.getPersonalCustomBeatmapRecord().values().stream() + .map(MusicGamePlayerData.CustomBeatmapRecord::toProto) + .map(MusicBriefInfoOuterClass.MusicBriefInfo.Builder::build) + .toList()) + + .addAllPersonCustomBeatmap(musicGamePlayerData.getOthersCustomBeatmapRecord().values().stream() + .map(MusicGamePlayerData.CustomBeatmapRecord::toProto) + .map(MusicBriefInfoOuterClass.MusicBriefInfo.Builder::build) + .toList()) + .build()); + } + + public MusicGamePlayerData getMusicGameRecord(PlayerActivityData playerActivityData){ + if(playerActivityData.getDetail() == null || playerActivityData.getDetail().isBlank()){ + onInitPlayerActivityData(playerActivityData); + playerActivityData.save(); + } + + return Grasscutter.getGsonFactory().fromJson(playerActivityData.getDetail(), + MusicGamePlayerData.class); + } + + public boolean setMusicGameRecord(PlayerActivityData playerActivityData, MusicGamePlayerData.MusicGameRecord newRecord){ + var musicGamePlayerData = getMusicGameRecord(playerActivityData); + var saveRecord = musicGamePlayerData.getMusicGameRecord().get(newRecord.getMusicId()); + + saveRecord.setMaxCombo(Math.max(newRecord.getMaxCombo(), saveRecord.getMaxCombo())); + saveRecord.setMaxScore(Math.max(newRecord.getMaxScore(), saveRecord.getMaxScore())); + + playerActivityData.setDetail(musicGamePlayerData); + playerActivityData.save(); + + return newRecord.getMaxScore() > saveRecord.getMaxScore(); + } + public void setMusicGameCustomBeatmapRecord(PlayerActivityData playerActivityData, MusicGamePlayerData.CustomBeatmapRecord newRecord){ + var musicGamePlayerData = getMusicGameRecord(playerActivityData); + musicGamePlayerData.getOthersCustomBeatmapRecord().put(newRecord.getMusicShareId(), newRecord); + + playerActivityData.setDetail(musicGamePlayerData); + playerActivityData.save(); + } + + public void addPersonalBeatmap(PlayerActivityData playerActivityData, MusicGameBeatmap musicGameBeatmap) { + var musicGamePlayerData = getMusicGameRecord(playerActivityData); + musicGamePlayerData.getPersonalCustomBeatmapRecord().put(musicGameBeatmap.getMusicShareId(), + MusicGamePlayerData.CustomBeatmapRecord.of() + .musicShareId(musicGameBeatmap.getMusicShareId()) + .build()); + + 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 new file mode 100644 index 000000000..0a5baaf39 --- /dev/null +++ b/src/main/java/emu/grasscutter/game/activity/musicgame/MusicGameBeatmap.java @@ -0,0 +1,109 @@ +package emu.grasscutter.game.activity.musicgame; + +import dev.morphia.annotations.Entity; +import dev.morphia.annotations.Id; +import emu.grasscutter.database.DatabaseHelper; +import emu.grasscutter.net.proto.MusicBeatmapListOuterClass; +import emu.grasscutter.net.proto.MusicBeatmapNoteOuterClass; +import emu.grasscutter.net.proto.MusicBeatmapOuterClass; +import emu.grasscutter.net.proto.MusicBriefInfoOuterClass; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Data; +import lombok.experimental.FieldDefaults; + +import java.util.List; +import java.util.Random; + +@Entity("music_game_beatmaps") +@Data +@FieldDefaults(level = AccessLevel.PRIVATE) +@Builder(builderMethodName = "of") +public class MusicGameBeatmap { + + @Id + long musicShareId; + int authorUid; + int musicId; + int musicNoteCount; + int savePosition; + int maxScore; + int createTime; + + List> beatmap; + + public static MusicGameBeatmap getByShareId(long musicShareId){ + return DatabaseHelper.getMusicGameBeatmap(musicShareId); + } + + public void save(){ + if(musicShareId == 0){ + musicShareId = new Random().nextLong(100000000000000L,999999999999999L); + } + DatabaseHelper.saveMusicGameBeatmap(this); + } + + public static List> parse(List beatmapItemListList) { + return beatmapItemListList.stream() + .map(item -> item.getBeatmapNoteListList().stream() + .map(BeatmapNote::parse) + .toList()) + .toList(); + } + + public MusicBeatmapOuterClass.MusicBeatmap toProto(){ + return MusicBeatmapOuterClass.MusicBeatmap.newBuilder() + .setMusicId(musicId) + .addAllBeatmapItemList(beatmap.stream() + .map(this::musicBeatmapListToProto) + .toList()) + .build(); + } + + public MusicBriefInfoOuterClass.MusicBriefInfo.Builder toBriefProto(){ + 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) + ; + } + + private MusicBeatmapListOuterClass.MusicBeatmapList musicBeatmapListToProto(List beatmapNoteList){ + return MusicBeatmapListOuterClass.MusicBeatmapList.newBuilder() + .addAllBeatmapNoteList(beatmapNoteList.stream() + .map(BeatmapNote::toProto) + .toList()) + .build(); + } + + @Data + @FieldDefaults(level = AccessLevel.PRIVATE) + @Builder(builderMethodName = "of") + @Entity + public static class BeatmapNote{ + int startTime; + int endTime; + + public static BeatmapNote parse(MusicBeatmapNoteOuterClass.MusicBeatmapNote note){ + return BeatmapNote.of() + .startTime(note.getStartTime()) + .endTime(note.getEndTime()) + .build(); + } + + public MusicBeatmapNoteOuterClass.MusicBeatmapNote toProto(){ + return MusicBeatmapNoteOuterClass.MusicBeatmapNote.newBuilder() + .setStartTime(startTime) + .setEndTime(endTime) + .build(); + } + } +} diff --git a/src/main/java/emu/grasscutter/game/activity/musicgame/MusicGamePlayerData.java b/src/main/java/emu/grasscutter/game/activity/musicgame/MusicGamePlayerData.java new file mode 100644 index 000000000..1492d93f9 --- /dev/null +++ b/src/main/java/emu/grasscutter/game/activity/musicgame/MusicGamePlayerData.java @@ -0,0 +1,76 @@ +package emu.grasscutter.game.activity.musicgame; + +import emu.grasscutter.data.GameData; +import emu.grasscutter.data.excels.MusicGameBasicData; +import emu.grasscutter.net.proto.MusicBriefInfoOuterClass; +import emu.grasscutter.net.proto.MusicGameRecordOuterClass; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Data; +import lombok.experimental.FieldDefaults; + +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; + +@Data +@FieldDefaults(level = AccessLevel.PRIVATE) +@Builder(builderMethodName = "of") +public class MusicGamePlayerData { + Map musicGameRecord; + Map personalCustomBeatmapRecord; + Map othersCustomBeatmapRecord; + + public static MusicGamePlayerData create(){ + return MusicGamePlayerData.of() + .musicGameRecord(GameData.getMusicGameBasicDataMap().values().stream() + .collect(Collectors.toMap(MusicGameBasicData::getId, MusicGamePlayerData.MusicGameRecord::create))) + .personalCustomBeatmapRecord(new HashMap<>()) + .othersCustomBeatmapRecord(new HashMap<>()) + .build(); + } + + @Data + @FieldDefaults(level = AccessLevel.PRIVATE) + @Builder(builderMethodName = "of") + public static class MusicGameRecord { + int musicId; + int maxCombo; + int maxScore; + + public static MusicGameRecord create(MusicGameBasicData musicGameBasicData){ + return MusicGameRecord.of() + .musicId(musicGameBasicData.getId()) + .build(); + } + + public MusicGameRecordOuterClass.MusicGameRecord toProto(){ + return MusicGameRecordOuterClass.MusicGameRecord.newBuilder() + .setIsUnlock(true) + .setMaxCombo(maxCombo) + .setMaxScore(maxScore) + .build(); + } + } + + @Data + @FieldDefaults(level = AccessLevel.PRIVATE) + @Builder(builderMethodName = "of") + public static class CustomBeatmapRecord { + long musicShareId; + int score; + boolean settle; + + public MusicBriefInfoOuterClass.MusicBriefInfo.Builder toProto(){ + var musicGameBeatmap = MusicGameBeatmap.getByShareId(musicShareId); + + return musicGameBeatmap.toBriefProto() + .setScore(score) + .setSettle(settle) + ; + } + + } +} + + diff --git a/src/main/java/emu/grasscutter/game/activity/musicgame/MusicGameScoreTrigger.java b/src/main/java/emu/grasscutter/game/activity/musicgame/MusicGameScoreTrigger.java index 8ee92027f..34cfbe257 100644 --- a/src/main/java/emu/grasscutter/game/activity/musicgame/MusicGameScoreTrigger.java +++ b/src/main/java/emu/grasscutter/game/activity/musicgame/MusicGameScoreTrigger.java @@ -1,10 +1,10 @@ package emu.grasscutter.game.activity.musicgame; import emu.grasscutter.game.activity.ActivityWatcher; -import emu.grasscutter.game.activity.WatcherType; +import emu.grasscutter.game.activity.ActivityWatcherType; import emu.grasscutter.game.props.WatcherTriggerType; -@WatcherType(WatcherTriggerType.TRIGGER_FLEUR_FAIR_MUSIC_GAME_REACH_SCORE) +@ActivityWatcherType(WatcherTriggerType.TRIGGER_FLEUR_FAIR_MUSIC_GAME_REACH_SCORE) public class MusicGameScoreTrigger extends ActivityWatcher { @Override protected boolean isMeet(String... param) { diff --git a/src/main/java/emu/grasscutter/game/props/ActivityType.java b/src/main/java/emu/grasscutter/game/props/ActivityType.java new file mode 100644 index 000000000..b91538cbb --- /dev/null +++ b/src/main/java/emu/grasscutter/game/props/ActivityType.java @@ -0,0 +1,38 @@ +package emu.grasscutter.game.props; + +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Stream; + +@Getter +@AllArgsConstructor +public enum ActivityType { + NONE(0), + NEW_ACTIVITY_MUSIC_GAME(2202), + + ; + + private final int value; + private static final Int2ObjectMap map = new Int2ObjectOpenHashMap<>(); + private static final Map stringMap = new HashMap<>(); + + static { + Stream.of(values()).forEach(e -> { + map.put(e.getValue(), e); + stringMap.put(e.name(), e); + }); + } + + public static ActivityType getTypeByValue(int value) { + return map.getOrDefault(value, NONE); + } + + public static ActivityType getTypeByName(String name) { + return stringMap.getOrDefault(name, NONE); + } +} diff --git a/src/main/java/emu/grasscutter/net/packet/PacketOpcodes.java b/src/main/java/emu/grasscutter/net/packet/PacketOpcodes.java index af37f7a05..9582b6fe0 100644 --- a/src/main/java/emu/grasscutter/net/packet/PacketOpcodes.java +++ b/src/main/java/emu/grasscutter/net/packet/PacketOpcodes.java @@ -899,6 +899,12 @@ public class PacketOpcodes { public static final int MultistagePlayInfoNotify = 5309; public static final int MultistagePlaySettleNotify = 5314; public static final int MultistagePlayStageEndNotify = 5340; + public static final int MusicGameCreateBeatmapReq = 6326; + public static final int MusicGameCreateBeatmapRsp = 6347; + public static final int MusicGameGetBeatmapReq = 6318; + public static final int MusicGameGetBeatmapRsp = 6309; + public static final int MusicGameSearchBeatmapReq = 6343; + public static final int MusicGameSearchBeatmapRsp = 6304; public static final int MusicGameSettleReq = 8745; public static final int MusicGameSettleRsp = 8288; public static final int MusicGameStartReq = 8927; diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerActivityTakeWatcherRewardReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerActivityTakeWatcherRewardReq.java new file mode 100644 index 000000000..3ea3b75e2 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerActivityTakeWatcherRewardReq.java @@ -0,0 +1,25 @@ +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.ActivityTakeWatcherRewardReqOuterClass; +import emu.grasscutter.server.game.GameSession; +import emu.grasscutter.server.packet.send.PacketActivityTakeWatcherRewardRsp; + +import java.util.Optional; + +@Opcodes(PacketOpcodes.ActivityTakeWatcherRewardReq) +public class HandlerActivityTakeWatcherRewardReq extends PacketHandler { + + @Override + public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { + var req = ActivityTakeWatcherRewardReqOuterClass.ActivityTakeWatcherRewardReq.parseFrom(payload); + + Optional.ofNullable(session.getPlayer().getActivityManager().getPlayerActivityDataMap().get(req.getActivityId())) + .ifPresent(x -> x.takeWatcherReward(req.getWatcherId())); + + session.send(new PacketActivityTakeWatcherRewardRsp(req.getActivityId(), req.getWatcherId())); + } + +} diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerMusicGameCreateBeatmapReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerMusicGameCreateBeatmapReq.java new file mode 100644 index 000000000..b3ac7ef84 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerMusicGameCreateBeatmapReq.java @@ -0,0 +1,47 @@ +package emu.grasscutter.server.packet.recv; + +import emu.grasscutter.game.activity.musicgame.MusicGameActivityHandler; +import emu.grasscutter.game.activity.musicgame.MusicGameBeatmap; +import emu.grasscutter.game.props.ActivityType; +import emu.grasscutter.net.packet.Opcodes; +import emu.grasscutter.net.packet.PacketHandler; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.proto.MusicGameCreateBeatmapReqOuterClass; +import emu.grasscutter.server.game.GameSession; +import emu.grasscutter.server.packet.send.PacketActivityInfoNotify; +import emu.grasscutter.server.packet.send.PacketMusicGameCreateBeatmapRsp; +import emu.grasscutter.utils.Utils; + +@Opcodes(PacketOpcodes.MusicGameCreateBeatmapReq) +public class HandlerMusicGameCreateBeatmapReq extends PacketHandler { + + @Override + public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { + var req = MusicGameCreateBeatmapReqOuterClass.MusicGameCreateBeatmapReq.parseFrom(payload); + + var musicGameBeatmap = MusicGameBeatmap.of() + .musicId(req.getMusicBriefInfo().getMusicId()) + .musicNoteCount(req.getMusicBriefInfo().getMusicNoteCount()) + .savePosition(req.getMusicBriefInfo().getSavePosition()) + .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); + if(playerData.isEmpty()){ + return; + } + + var handler = (MusicGameActivityHandler) playerData.get().getActivityHandler(); + handler.addPersonalBeatmap(playerData.get(), musicGameBeatmap); + + session.send(new PacketActivityInfoNotify(handler.toProto(playerData.get()))); + session.send(new PacketMusicGameCreateBeatmapRsp(musicGameBeatmap.getMusicShareId(), req.getUnknownEnum1())); + } + +} diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerMusicGameGetBeatmapReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerMusicGameGetBeatmapReq.java new file mode 100644 index 000000000..8d18c3525 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerMusicGameGetBeatmapReq.java @@ -0,0 +1,31 @@ +package emu.grasscutter.server.packet.recv; + +import emu.grasscutter.game.activity.musicgame.MusicGameBeatmap; +import emu.grasscutter.net.packet.Opcodes; +import emu.grasscutter.net.packet.PacketHandler; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.proto.MusicGameGetBeatmapReqOuterClass; +import emu.grasscutter.server.game.GameSession; +import emu.grasscutter.server.packet.send.PacketMusicGameGetBeatmapRsp; + +@Opcodes(PacketOpcodes.MusicGameGetBeatmapReq) +public class HandlerMusicGameGetBeatmapReq extends PacketHandler { + + @Override + public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { + var req = MusicGameGetBeatmapReqOuterClass.MusicGameGetBeatmapReq.parseFrom(payload); + + var musicGameBeatmap = MusicGameBeatmap.getByShareId(req.getMusicShareId()); + + if(musicGameBeatmap == null){ + return; + } + + session.send(new PacketMusicGameGetBeatmapRsp( + musicGameBeatmap.toBriefProto().build(), + musicGameBeatmap.toProto(), + req + )); + } + +} diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerMusicGameSearchBeatmapReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerMusicGameSearchBeatmapReq.java new file mode 100644 index 000000000..82c6f45f1 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerMusicGameSearchBeatmapReq.java @@ -0,0 +1,28 @@ +package emu.grasscutter.server.packet.recv; + +import emu.grasscutter.game.activity.musicgame.MusicGameBeatmap; +import emu.grasscutter.net.packet.Opcodes; +import emu.grasscutter.net.packet.PacketHandler; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.proto.MusicGameSearchBeatmapReqOuterClass; +import emu.grasscutter.server.game.GameSession; +import emu.grasscutter.server.packet.send.PacketMusicGameSearchBeatmapRsp; + +@Opcodes(PacketOpcodes.MusicGameSearchBeatmapReq) +public class HandlerMusicGameSearchBeatmapReq extends PacketHandler { + + @Override + public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { + var req = MusicGameSearchBeatmapReqOuterClass.MusicGameSearchBeatmapReq.parseFrom(payload); + + var musicGameBeatmap = MusicGameBeatmap.getByShareId(req.getMusicShareId()); + + if(musicGameBeatmap == null){ + session.send(new PacketMusicGameSearchBeatmapRsp(11153, req.getUnknownEnum1())); + return; + } + + session.send(new PacketMusicGameSearchBeatmapRsp(musicGameBeatmap.toBriefProto().build(), req.getUnknownEnum1())); + } + +} diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerMusicGameSettleReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerMusicGameSettleReq.java index e4e83950f..b73a867e5 100644 --- a/src/main/java/emu/grasscutter/server/packet/recv/HandlerMusicGameSettleReq.java +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerMusicGameSettleReq.java @@ -1,11 +1,15 @@ package emu.grasscutter.server.packet.recv; +import emu.grasscutter.game.activity.musicgame.MusicGameActivityHandler; +import emu.grasscutter.game.activity.musicgame.MusicGamePlayerData; +import emu.grasscutter.game.props.ActivityType; import emu.grasscutter.game.props.WatcherTriggerType; import emu.grasscutter.net.packet.Opcodes; import emu.grasscutter.net.packet.PacketHandler; import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.proto.MusicGameSettleReqOuterClass; import emu.grasscutter.server.game.GameSession; +import emu.grasscutter.server.packet.send.PacketActivityInfoNotify; import emu.grasscutter.server.packet.send.PacketMusicGameSettleRsp; @Opcodes(PacketOpcodes.MusicGameSettleReq) @@ -15,15 +19,40 @@ public class HandlerMusicGameSettleReq extends PacketHandler { public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { var req = MusicGameSettleReqOuterClass.MusicGameSettleReq.parseFrom(payload); - session.getPlayer().getActivityManager().triggerWatcher( - WatcherTriggerType.TRIGGER_FLEUR_FAIR_MUSIC_GAME_REACH_SCORE, - String.valueOf(req.getMusicBasicId()), - String.valueOf(req.getScore()) + var playerData = session.getPlayer().getActivityManager().getPlayerActivityDataByActivityType(ActivityType.NEW_ACTIVITY_MUSIC_GAME); + if(playerData.isEmpty()){ + return; + } + var handler = (MusicGameActivityHandler) playerData.get().getActivityHandler(); + boolean isNewRecord = false; + // check if custom beatmap + if(req.getMusicShareId() == 0){ + session.getPlayer().getActivityManager().triggerWatcher( + WatcherTriggerType.TRIGGER_FLEUR_FAIR_MUSIC_GAME_REACH_SCORE, + String.valueOf(req.getMusicBasicId()), + String.valueOf(req.getScore()) ); + isNewRecord = handler.setMusicGameRecord(playerData.get(), + MusicGamePlayerData.MusicGameRecord.of() + .musicId(req.getMusicBasicId()) + .maxCombo(req.getMaxCombo()) + .maxScore(req.getScore()) + .build()); - //session.send(new PacketMusicGameSettleRsp(req.getMusicBasicId())); - session.send(new PacketMusicGameSettleRsp(req.getMusicBasicId())); + // update activity info + session.send(new PacketActivityInfoNotify(handler.toProto(playerData.get()))); + }else{ + handler.setMusicGameCustomBeatmapRecord(playerData.get(), + MusicGamePlayerData.CustomBeatmapRecord.of() + .musicShareId(req.getMusicShareId()) + .score(req.getMaxCombo()) + .settle(req.getSuccess()) + .build()); + } + + + session.send(new PacketMusicGameSettleRsp(req.getMusicBasicId(), req.getMusicShareId(), isNewRecord)); } } diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerMusicGameStartReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerMusicGameStartReq.java index a7bb22cf8..a5f92f53a 100644 --- a/src/main/java/emu/grasscutter/server/packet/recv/HandlerMusicGameStartReq.java +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerMusicGameStartReq.java @@ -9,12 +9,12 @@ import emu.grasscutter.server.packet.send.PacketMusicGameStartRsp; @Opcodes(PacketOpcodes.MusicGameStartReq) public class HandlerMusicGameStartReq extends PacketHandler { - + @Override public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { var req = MusicGameStartReqOuterClass.MusicGameStartReq.parseFrom(payload); - session.send(new PacketMusicGameStartRsp(req.getMusicBasicId())); + session.send(new PacketMusicGameStartRsp(req.getMusicBasicId(), req.getMusicShareId())); } } diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketActivityTakeWatcherRewardRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketActivityTakeWatcherRewardRsp.java new file mode 100644 index 000000000..5968198e4 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketActivityTakeWatcherRewardRsp.java @@ -0,0 +1,20 @@ +package emu.grasscutter.server.packet.send; + +import emu.grasscutter.net.packet.BasePacket; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.proto.ActivityTakeWatcherRewardRspOuterClass; + +public class PacketActivityTakeWatcherRewardRsp extends BasePacket { + + public PacketActivityTakeWatcherRewardRsp(int activityId, int watcherId) { + super(PacketOpcodes.ActivityTakeWatcherRewardRsp); + + var proto = ActivityTakeWatcherRewardRspOuterClass.ActivityTakeWatcherRewardRsp.newBuilder(); + + proto.setActivityId(activityId) + .setWatcherId(watcherId); + + this.setData(proto); + } + +} diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketGetActivityInfoRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketGetActivityInfoRsp.java index 36e35dcb4..d0172bfcd 100644 --- a/src/main/java/emu/grasscutter/server/packet/send/PacketGetActivityInfoRsp.java +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketGetActivityInfoRsp.java @@ -14,7 +14,7 @@ public class PacketGetActivityInfoRsp extends BasePacket { var proto = GetActivityInfoRsp.newBuilder(); activityIdList.stream() - .map(activityManager::getInfoProto) + .map(activityManager::getInfoProtoByActivityId) .forEach(proto::addActivityInfoList); this.setData(proto); diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketMusicGameCreateBeatmapRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketMusicGameCreateBeatmapRsp.java new file mode 100644 index 000000000..401ff44cc --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketMusicGameCreateBeatmapRsp.java @@ -0,0 +1,20 @@ +package emu.grasscutter.server.packet.send; + +import emu.grasscutter.net.packet.BasePacket; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.proto.MusicGameCreateBeatmapRspOuterClass; +import emu.grasscutter.net.proto.MusicGameUnknown1EnumOuterClass; + +public class PacketMusicGameCreateBeatmapRsp extends BasePacket { + + public PacketMusicGameCreateBeatmapRsp(long musicShareId, MusicGameUnknown1EnumOuterClass.MusicGameUnknown1Enum unknownEnum1) { + super(PacketOpcodes.MusicGameCreateBeatmapRsp); + + var proto = MusicGameCreateBeatmapRspOuterClass.MusicGameCreateBeatmapRsp.newBuilder(); + + proto.setMusicShareId(musicShareId) + .setUnknownEnum1(unknownEnum1); + + this.setData(proto); + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketMusicGameGetBeatmapRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketMusicGameGetBeatmapRsp.java new file mode 100644 index 000000000..35cbdfb3c --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketMusicGameGetBeatmapRsp.java @@ -0,0 +1,27 @@ +package emu.grasscutter.server.packet.send; + +import emu.grasscutter.net.packet.BasePacket; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.proto.MusicBeatmapOuterClass; +import emu.grasscutter.net.proto.MusicBriefInfoOuterClass; +import emu.grasscutter.net.proto.MusicGameGetBeatmapReqOuterClass; +import emu.grasscutter.net.proto.MusicGameGetBeatmapRspOuterClass; + +public class PacketMusicGameGetBeatmapRsp extends BasePacket { + + public PacketMusicGameGetBeatmapRsp(MusicBriefInfoOuterClass.MusicBriefInfo briefInfo, MusicBeatmapOuterClass.MusicBeatmap musicRecord, MusicGameGetBeatmapReqOuterClass.MusicGameGetBeatmapReq req) { + super(PacketOpcodes.MusicGameGetBeatmapRsp); + + var proto = MusicGameGetBeatmapRspOuterClass.MusicGameGetBeatmapRsp.newBuilder(); + + proto.setMusicBriefInfo(briefInfo) + .setMusicShareId(briefInfo.getMusicShareId()) + .setMusicRecord(musicRecord) + .setUnknownEnum1(req.getUnknownEnum1()) + .setReqType(req.getReqType()) + ; + + + this.setData(proto); + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketMusicGameSearchBeatmapRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketMusicGameSearchBeatmapRsp.java new file mode 100644 index 000000000..e5dc218ff --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketMusicGameSearchBeatmapRsp.java @@ -0,0 +1,34 @@ +package emu.grasscutter.server.packet.send; + +import emu.grasscutter.net.packet.BasePacket; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.proto.MusicBriefInfoOuterClass; +import emu.grasscutter.net.proto.MusicGameSearchBeatmapRspOuterClass; +import emu.grasscutter.net.proto.MusicGameUnknown1EnumOuterClass; + +public class PacketMusicGameSearchBeatmapRsp extends BasePacket { + + public PacketMusicGameSearchBeatmapRsp(int ret, MusicGameUnknown1EnumOuterClass.MusicGameUnknown1Enum unknownEnum1) { + super(PacketOpcodes.MusicGameSearchBeatmapRsp); + + var proto = MusicGameSearchBeatmapRspOuterClass.MusicGameSearchBeatmapRsp.newBuilder(); + + proto.setRetcode(ret) + .setUnknownEnum1(unknownEnum1); + + this.setData(proto); + } + + public PacketMusicGameSearchBeatmapRsp(MusicBriefInfoOuterClass.MusicBriefInfo briefInfo, MusicGameUnknown1EnumOuterClass.MusicGameUnknown1Enum unknownEnum1) { + super(PacketOpcodes.MusicGameSearchBeatmapRsp); + + var proto = MusicGameSearchBeatmapRspOuterClass.MusicGameSearchBeatmapRsp.newBuilder(); + + proto.setMusicBriefInfo(briefInfo) + .setUnknownEnum1(unknownEnum1); + + this.setData(proto); + } + + +} diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketMusicGameSettleRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketMusicGameSettleRsp.java index c64e44f71..6651f8c06 100644 --- a/src/main/java/emu/grasscutter/server/packet/send/PacketMusicGameSettleRsp.java +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketMusicGameSettleRsp.java @@ -6,14 +6,15 @@ import emu.grasscutter.net.proto.MusicGameSettleRspOuterClass; public class PacketMusicGameSettleRsp extends BasePacket { - public PacketMusicGameSettleRsp(int musicBasicId) { - super(PacketOpcodes.MusicGameSettleRsp); + public PacketMusicGameSettleRsp(int musicBasicId, long musicShareId, boolean isNewRecord) { + super(PacketOpcodes.MusicGameSettleRsp); - var proto = MusicGameSettleRspOuterClass.MusicGameSettleRsp.newBuilder(); + var proto = MusicGameSettleRspOuterClass.MusicGameSettleRsp.newBuilder(); - proto.setMusicBasicId(musicBasicId) - .setIsNewRecord(true); + proto.setMusicBasicId(musicBasicId) + .setMusicShareId(musicShareId) + .setIsNewRecord(isNewRecord); - this.setData(proto); - } + this.setData(proto); + } } diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketMusicGameStartRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketMusicGameStartRsp.java index 2dce1ba7c..86e11442c 100644 --- a/src/main/java/emu/grasscutter/server/packet/send/PacketMusicGameStartRsp.java +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketMusicGameStartRsp.java @@ -6,12 +6,13 @@ import emu.grasscutter.net.proto.MusicGameStartRspOuterClass; public class PacketMusicGameStartRsp extends BasePacket { - public PacketMusicGameStartRsp(int musicBasicId) { + public PacketMusicGameStartRsp(int musicBasicId, long musicShareId) { super(PacketOpcodes.MusicGameStartRsp); var proto = MusicGameStartRspOuterClass.MusicGameStartRsp.newBuilder(); - proto.setMusicBasicId(musicBasicId); + proto.setMusicBasicId(musicBasicId) + .setMusicShareId(musicShareId); this.setData(proto); } diff --git a/src/main/resources/defaults/data/ActivityConfig.json b/src/main/resources/defaults/data/ActivityConfig.json index 75314fdb9..6291aea43 100644 --- a/src/main/resources/defaults/data/ActivityConfig.json +++ b/src/main/resources/defaults/data/ActivityConfig.json @@ -2,6 +2,7 @@ { "activityId" : 5072, "activityType" : 2202, + "scheduleId": 5072001, "meetCondList" : [ 5072001, 5072002, @@ -9,7 +10,10 @@ 5072004, 5072005, 5072006, - 5072007 + 5072007, + 5072008, + 5072009, + 5072013 ], "beginTime" : "2022-05-01T00:00:00+08:00", "endTime" : "2023-05-01T00:00:00+08:00"