Skip to content
Snippets Groups Projects
Commit 977f1ca2 authored by Akka's avatar Akka Committed by Melledy
Browse files

implement the activity system

parent 5d35cb49
Branches
Tags
No related merge requests found
Showing
with 586 additions and 6 deletions
...@@ -15,6 +15,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap; ...@@ -15,6 +15,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.ints.IntList;
import lombok.Getter;
public class GameData { public class GameData {
// BinOutputs // BinOutputs
...@@ -98,6 +99,9 @@ public class GameData { ...@@ -98,6 +99,9 @@ public class GameData {
private static final Int2ObjectMap<BattlePassMissionData> battlePassMissionDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<BattlePassMissionData> battlePassMissionDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<BattlePassRewardData> battlePassRewardDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<BattlePassRewardData> battlePassRewardDataMap = new Int2ObjectOpenHashMap<>();
@Getter private static final Int2ObjectMap<ActivityData> activityDataMap = new Int2ObjectOpenHashMap<>();
@Getter private static final Int2ObjectMap<ActivityWatcherData> activityWatcherDataMap = new Int2ObjectOpenHashMap<>();
// Cache // Cache
private static Map<Integer, List<Integer>> fetters = new HashMap<>(); private static Map<Integer, List<Integer>> fetters = new HashMap<>();
private static Map<Integer, List<ShopGoodsData>> shopGoods = new HashMap<>(); private static Map<Integer, List<ShopGoodsData>> shopGoods = new HashMap<>();
......
package emu.grasscutter.data.excels;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.experimental.FieldDefaults;
import java.util.List;
import java.util.Objects;
@ResourceType(name = "NewActivityExcelConfigData.json", loadPriority = ResourceType.LoadPriority.LOW)
@Getter
@FieldDefaults(level = AccessLevel.PRIVATE)
public class ActivityData extends GameResource {
int activityId;
String activityType;
List<Integer> condGroupId;
List<Integer> watcherId;
List<ActivityWatcherData> watcherDataList;
@Override
public int getId() {
return this.activityId;
}
@Override
public void onLoad() {
this.watcherDataList = watcherId.stream().map(item -> GameData.getActivityWatcherDataMap().get(item.intValue()))
.filter(Objects::nonNull)
.toList();
}
}
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;
import java.util.List;
@ResourceType(name = "NewActivityWatcherConfigData.json", loadPriority = ResourceType.LoadPriority.HIGH)
@Getter
@FieldDefaults(level = AccessLevel.PRIVATE)
public class ActivityWatcherData extends GameResource {
int id;
int rewardID;
int progress;
WatcherTrigger triggerConfig;
@Override
public int getId() {
return this.id;
}
@Override
public void onLoad() {
triggerConfig.paramList = triggerConfig.paramList.stream().filter(x -> !x.isBlank()).toList();
}
@Getter
@FieldDefaults(level = AccessLevel.PRIVATE)
public static class WatcherTrigger{
String triggerType;
List<String> paramList;
}
}
...@@ -10,6 +10,7 @@ import dev.morphia.query.experimental.filters.Filters; ...@@ -10,6 +10,7 @@ import dev.morphia.query.experimental.filters.Filters;
import emu.grasscutter.GameConstants; import emu.grasscutter.GameConstants;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.Account; import emu.grasscutter.game.Account;
import emu.grasscutter.game.activity.PlayerActivityData;
import emu.grasscutter.game.avatar.Avatar; import emu.grasscutter.game.avatar.Avatar;
import emu.grasscutter.game.battlepass.BattlePassManager; import emu.grasscutter.game.battlepass.BattlePassManager;
import emu.grasscutter.game.friends.Friendship; import emu.grasscutter.game.friends.Friendship;
...@@ -326,4 +327,14 @@ public final class DatabaseHelper { ...@@ -326,4 +327,14 @@ public final class DatabaseHelper {
public static void saveBattlePass(BattlePassManager manager) { public static void saveBattlePass(BattlePassManager manager) {
DatabaseManager.getGameDatastore().save(manager); DatabaseManager.getGameDatastore().save(manager);
} }
public static PlayerActivityData getPlayerActivityData(int uid, int activityId) {
return DatabaseManager.getGameDatastore().find(PlayerActivityData.class)
.filter(Filters.and(Filters.eq("uid", uid),Filters.eq("activityId", activityId)))
.first();
}
public static void savePlayerActivityData(PlayerActivityData playerActivityData) {
DatabaseManager.getGameDatastore().save(playerActivityData);
}
} }
...@@ -13,6 +13,7 @@ import dev.morphia.query.experimental.filters.Filters; ...@@ -13,6 +13,7 @@ import dev.morphia.query.experimental.filters.Filters;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.Grasscutter.ServerRunMode; import emu.grasscutter.Grasscutter.ServerRunMode;
import emu.grasscutter.game.Account; import emu.grasscutter.game.Account;
import emu.grasscutter.game.activity.PlayerActivityData;
import emu.grasscutter.game.avatar.Avatar; import emu.grasscutter.game.avatar.Avatar;
import emu.grasscutter.game.battlepass.BattlePassManager; import emu.grasscutter.game.battlepass.BattlePassManager;
import emu.grasscutter.game.friends.Friendship; import emu.grasscutter.game.friends.Friendship;
...@@ -32,9 +33,8 @@ public final class DatabaseManager { ...@@ -32,9 +33,8 @@ public final class DatabaseManager {
private static final Class<?>[] mappedClasses = new Class<?>[] { private static final Class<?>[] mappedClasses = new Class<?>[] {
DatabaseCounter.class, Account.class, Player.class, Avatar.class, GameItem.class, Friendship.class, DatabaseCounter.class, Account.class, Player.class, Avatar.class, GameItem.class, Friendship.class,
GachaRecord.class, Mail.class, GameMainQuest.class, GameHome.class, BattlePassManager.class GachaRecord.class, Mail.class, GameMainQuest.class, GameHome.class, BattlePassManager.class, PlayerActivityData.class
}; };
public static Datastore getGameDatastore() { public static Datastore getGameDatastore() {
return gameDatastore; return gameDatastore;
} }
......
package emu.grasscutter.game.activity;
import lombok.AccessLevel;
import lombok.Data;
import lombok.experimental.FieldDefaults;
import java.util.Date;
import java.util.List;
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
public class ActivityConfigItem {
int activityId;
int activityType;
int scheduleId;
List<Integer> meetCondList;
Date beginTime;
Date endTime;
transient ActivityHandler activityHandler;
}
package emu.grasscutter.game.activity;
import com.esotericsoftware.reflectasm.ConstructorAccess;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.ActivityData;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.WatcherTriggerType;
import emu.grasscutter.net.proto.ActivityInfoOuterClass;
import emu.grasscutter.utils.DateHelper;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.FieldDefaults;
import java.util.*;
import java.util.stream.Collectors;
@Getter
@Setter
@FieldDefaults(level = AccessLevel.PRIVATE)
public abstract class ActivityHandler {
/**
* Must set before initWatchers
*/
ActivityConfigItem activityConfigItem;
ActivityData activityData;
Map<WatcherTriggerType, List<ActivityWatcher>> watchersMap = new HashMap<>();
public void initWatchers(HashMap<String, ConstructorAccess<?>> activityWatcherTypeMap){
activityData = GameData.getActivityDataMap().get(activityConfigItem.getActivityId());
// add watcher to map by id
activityData.getWatcherDataList().forEach(watcherData -> {
var watcherType = activityWatcherTypeMap.get(watcherData.getTriggerConfig().getTriggerType());
ActivityWatcher watcher;
if(watcherType != null){
watcher = (ActivityWatcher) watcherType.newInstance();
}else{
watcher = new DefaultWatcher();
}
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);
});
}
private Map<Integer, PlayerActivityData.WatcherInfo> initWatchersDataForPlayer(){
return watchersMap.values().stream()
.flatMap(Collection::stream)
.map(PlayerActivityData.WatcherInfo::init)
.collect(Collectors.toMap(PlayerActivityData.WatcherInfo::getWatcherId, y -> y));
}
public PlayerActivityData initPlayerActivityData(Player player){
return PlayerActivityData.of()
.activityId(activityConfigItem.getActivityId())
.uid(player.getUid())
.watcherInfoMap(initWatchersDataForPlayer())
.build();
}
public void buildProto(PlayerActivityData playerActivityData, ActivityInfoOuterClass.ActivityInfo.Builder activityInfo){
activityInfo.setActivityId(activityConfigItem.getActivityId())
.setActivityType(activityConfigItem.getActivityType())
.setScheduleId(activityConfigItem.getScheduleId())
.setBeginTime(DateHelper.getUnixTime(activityConfigItem.getBeginTime()))
.setFirstDayStartTime(DateHelper.getUnixTime(activityConfigItem.getBeginTime()))
.setEndTime(DateHelper.getUnixTime(activityConfigItem.getEndTime()))
.addAllMeetCondList(activityConfigItem.getMeetCondList());
if (playerActivityData != null){
activityInfo.addAllWatcherInfoList(playerActivityData.getAllWatcherInfoList());
}
}
}
package emu.grasscutter.game.activity;
import com.esotericsoftware.reflectasm.ConstructorAccess;
import com.google.gson.reflect.TypeToken;
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.WatcherTriggerType;
import emu.grasscutter.net.proto.ActivityInfoOuterClass;
import emu.grasscutter.server.packet.send.PacketActivityScheduleInfoNotify;
import lombok.Getter;
import org.reflections.Reflections;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
@Getter
public class ActivityManager {
private static final Map<Integer, ActivityConfigItem> activityConfigItemMap;
private final Player player;
private final Map<Integer, PlayerActivityData> playerActivityDataMap;
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<String, ConstructorAccess<?>>();
var activityWatcherTypeMap = new HashMap<String, ConstructorAccess<?>>();
var reflections = new Reflections(ActivityManager.class.getPackage().getName());
reflections.getSubTypesOf(ActivityHandler.class).forEach(item -> {
var typeName = item.getAnnotation(ActivityType.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));
});
try(InputStream is = DataLoader.load("ActivityConfig.json"); InputStreamReader isr = new InputStreamReader(is)) {
List<ActivityConfigItem> activities = Grasscutter.getGsonFactory().fromJson(
isr,
TypeToken.getParameterized(List.class, ActivityConfigItem.class).getType());
activities.forEach(item -> {
var activityData = GameData.getActivityDataMap().get(item.getActivityId());
if(activityData == null){
Grasscutter.getLogger().warn("activity {} not exist.", item.getActivityId());
return;
}
var activityHandlerType = activityHandlerTypeMap.get(activityData.getActivityType());
if(activityHandlerType != null) {
var activityHandler = (ActivityHandler) activityHandlerType.newInstance();
activityHandler.setActivityConfigItem(item);
activityHandler.initWatchers(activityWatcherTypeMap);
item.setActivityHandler(activityHandler);
}
activityConfigItemMap.putIfAbsent(item.getActivityId(), item);
});
Grasscutter.getLogger().error("Enable {} activities.", activityConfigItemMap.size());
} catch (Exception e) {
Grasscutter.getLogger().error("Unable to load chest reward config.", e);
}
}
public ActivityInfoOuterClass.ActivityInfo getInfoProto(int activityId){
var activityHandler = activityConfigItemMap.get(activityId).getActivityHandler();
var activityData = playerActivityDataMap.get(activityId);
var proto = ActivityInfoOuterClass.ActivityInfo.newBuilder();
activityHandler.buildProto(activityData, proto);
return proto.build();
}
/**
* trigger activity watcher
* @param watcherTriggerType
* @param params
*/
public void triggerWatcher(WatcherTriggerType watcherTriggerType, String... params) {
var watchers = activityConfigItemMap.values().stream()
.map(ActivityConfigItem::getActivityHandler)
.filter(Objects::nonNull)
.map(ActivityHandler::getWatchersMap)
.map(map -> map.get(watcherTriggerType))
.filter(Objects::nonNull)
.flatMap(Collection::stream)
.toList();
watchers.forEach(watcher -> watcher.trigger(
playerActivityDataMap.get(watcher.getActivityHandler().getActivityConfigItem().getActivityId()),
params));
}
}
package emu.grasscutter.game.activity;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ActivityType {
String value();
}
package emu.grasscutter.game.activity;
import emu.grasscutter.data.excels.ActivityWatcherData;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.FieldDefaults;
@Getter
@Setter
@FieldDefaults(level = AccessLevel.PRIVATE)
public abstract class ActivityWatcher {
int watcherId;
ActivityWatcherData activityWatcherData;
ActivityHandler activityHandler;
protected abstract boolean isMeet(String... param);
public void trigger(PlayerActivityData playerActivityData, String... param){
if(isMeet(param)){
playerActivityData.addWatcherProgress(watcherId);
playerActivityData.save();
}
}
}
package emu.grasscutter.game.activity;
import emu.grasscutter.game.props.WatcherTriggerType;
@WatcherType(WatcherTriggerType.TRIGGER_NONE)
public class DefaultWatcher extends ActivityWatcher{
@Override
protected boolean isMeet(String... param) {
return false;
}
}
package emu.grasscutter.game.activity;
import dev.morphia.annotations.Entity;
import dev.morphia.annotations.Id;
import dev.morphia.annotations.Transient;
import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.net.proto.ActivityWatcherInfoOuterClass;
import emu.grasscutter.server.packet.send.PacketActivityUpdateWatcherNotify;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.FieldDefaults;
import java.util.List;
import java.util.Map;
@Entity("activities")
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
@Builder(builderMethodName = "of")
public class PlayerActivityData {
@Id
String id;
int uid;
int activityId;
Map<Integer, WatcherInfo> watcherInfoMap;
String detail;
@Transient Player player;
public void save(){
DatabaseHelper.savePlayerActivityData(this);
}
public static PlayerActivityData getByPlayer(Player player, int activityId){
return DatabaseHelper.getPlayerActivityData(player.getUid(), activityId);
}
public synchronized void addWatcherProgress(int watcherId){
var watcherInfo = watcherInfoMap.get(watcherId);
if(watcherInfo == null){
return;
}
if(watcherInfo.curProgress >= watcherInfo.totalProgress){
return;
}
watcherInfo.curProgress++;
getPlayer().sendPacket(new PacketActivityUpdateWatcherNotify(activityId, watcherInfo));
}
public List<ActivityWatcherInfoOuterClass.ActivityWatcherInfo> getAllWatcherInfoList() {
return watcherInfoMap.values().stream()
.map(WatcherInfo::toProto)
.toList();
}
@Entity
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
@Builder(builderMethodName = "of")
public static class WatcherInfo{
int watcherId;
int totalProgress;
int curProgress;
boolean isTakenReward;
public static WatcherInfo init(ActivityWatcher watcher){
return WatcherInfo.of()
.watcherId(watcher.getWatcherId())
.totalProgress(watcher.getActivityWatcherData().getProgress())
.isTakenReward(false)
.build();
}
public ActivityWatcherInfoOuterClass.ActivityWatcherInfo toProto(){
return ActivityWatcherInfoOuterClass.ActivityWatcherInfo.newBuilder()
.setWatcherId(watcherId)
.setCurProgress(curProgress)
.setTotalProgress(totalProgress)
.setIsTakenReward(isTakenReward)
.build();
}
}
}
package emu.grasscutter.game.activity;
import emu.grasscutter.game.props.WatcherTriggerType;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface WatcherType {
WatcherTriggerType value();
}
package emu.grasscutter.game.activity.musicgame;
import emu.grasscutter.game.activity.ActivityHandler;
import emu.grasscutter.game.activity.ActivityType;
import emu.grasscutter.game.activity.PlayerActivityData;
import emu.grasscutter.net.proto.ActivityInfoOuterClass;
@ActivityType("NEW_ACTIVITY_MUSIC_GAME")
public class MusicGameActivityHandler extends ActivityHandler {
@Override
public void buildProto(PlayerActivityData playerActivityData, ActivityInfoOuterClass.ActivityInfo.Builder activityInfo) {
super.buildProto(playerActivityData, activityInfo);
}
}
package emu.grasscutter.game.activity.musicgame;
import emu.grasscutter.game.activity.ActivityWatcher;
import emu.grasscutter.game.activity.WatcherType;
import emu.grasscutter.game.props.WatcherTriggerType;
@WatcherType(WatcherTriggerType.TRIGGER_FLEUR_FAIR_MUSIC_GAME_REACH_SCORE)
public class MusicGameScoreTrigger extends ActivityWatcher {
@Override
protected boolean isMeet(String... param) {
if(param.length != 2){
return false;
}
var paramList = getActivityWatcherData().getTriggerConfig().getParamList();
if(!paramList.get(0).equals(param[0])){
return false;
}
var score = Integer.parseInt(param[1]);
var target = Integer.parseInt(paramList.get(1));
return score >= target;
}
}
...@@ -11,6 +11,7 @@ import emu.grasscutter.database.DatabaseManager; ...@@ -11,6 +11,7 @@ import emu.grasscutter.database.DatabaseManager;
import emu.grasscutter.game.Account; import emu.grasscutter.game.Account;
import emu.grasscutter.game.CoopRequest; import emu.grasscutter.game.CoopRequest;
import emu.grasscutter.game.ability.AbilityManager; import emu.grasscutter.game.ability.AbilityManager;
import emu.grasscutter.game.activity.ActivityManager;
import emu.grasscutter.game.avatar.Avatar; import emu.grasscutter.game.avatar.Avatar;
import emu.grasscutter.game.avatar.AvatarProfileData; import emu.grasscutter.game.avatar.AvatarProfileData;
import emu.grasscutter.game.avatar.AvatarStorage; import emu.grasscutter.game.avatar.AvatarStorage;
...@@ -183,6 +184,7 @@ public class Player { ...@@ -183,6 +184,7 @@ public class Player {
@Transient private GameHome home; @Transient private GameHome home;
@Transient private FurnitureManager furnitureManager; @Transient private FurnitureManager furnitureManager;
@Transient private BattlePassManager battlePassManager; @Transient private BattlePassManager battlePassManager;
@Getter @Transient private ActivityManager activityManager;
@Transient private CollectionManager collectionManager; @Transient private CollectionManager collectionManager;
private CollectionRecordStore collectionRecordStore; private CollectionRecordStore collectionRecordStore;
...@@ -1513,6 +1515,8 @@ public class Player { ...@@ -1513,6 +1515,8 @@ public class Player {
// Home // Home
home = GameHome.getByUid(getUid()); home = GameHome.getByUid(getUid());
home.onOwnerLogin(this); home.onOwnerLogin(this);
// Activity
activityManager = new ActivityManager(this);
session.send(new PacketPlayerEnterSceneNotify(this)); // Enter game world session.send(new PacketPlayerEnterSceneNotify(this)); // Enter game world
session.send(new PacketPlayerLevelRewardUpdateNotify(rewardedLevels)); session.send(new PacketPlayerLevelRewardUpdateNotify(rewardedLevels));
......
...@@ -3,13 +3,20 @@ package emu.grasscutter.server.packet.recv; ...@@ -3,13 +3,20 @@ package emu.grasscutter.server.packet.recv;
import emu.grasscutter.net.packet.Opcodes; import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.packet.PacketHandler; import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.proto.GetActivityInfoReqOuterClass;
import emu.grasscutter.server.game.GameSession; import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketGetActivityInfoRsp; import emu.grasscutter.server.packet.send.PacketGetActivityInfoRsp;
import java.util.HashSet;
@Opcodes(PacketOpcodes.GetActivityInfoReq) @Opcodes(PacketOpcodes.GetActivityInfoReq)
public class HandlerGetActivityInfoReq extends PacketHandler { public class HandlerGetActivityInfoReq extends PacketHandler {
@Override @Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
session.send(new PacketGetActivityInfoRsp()); var req = GetActivityInfoReqOuterClass.GetActivityInfoReq.parseFrom(payload);
session.send(new PacketGetActivityInfoRsp(
new HashSet<>(req.getActivityIdListList()),
session.getPlayer().getActivityManager()));
} }
} }
package emu.grasscutter.server.packet.recv;
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.PacketMusicGameSettleRsp;
@Opcodes(PacketOpcodes.MusicGameSettleReq)
public class HandlerMusicGameSettleReq extends PacketHandler {
@Override
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())
);
//session.send(new PacketMusicGameSettleRsp(req.getMusicBasicId()));
session.send(new PacketMusicGameSettleRsp(req.getMusicBasicId()));
}
}
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.MusicGameStartReqOuterClass;
import emu.grasscutter.server.game.GameSession;
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()));
}
}
package emu.grasscutter.server.packet.send;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.ActivityInfoNotifyOuterClass;
import emu.grasscutter.net.proto.ActivityInfoOuterClass;
public class PacketActivityInfoNotify extends BasePacket {
public PacketActivityInfoNotify(ActivityInfoOuterClass.ActivityInfo activityInfo) {
super(PacketOpcodes.ActivityInfoNotify);
var proto = ActivityInfoNotifyOuterClass.ActivityInfoNotify.newBuilder();
proto.setActivityInfo(activityInfo);
this.setData(proto);
}
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment