ActivityManager.java 5.93 KB
Newer Older
Akka's avatar
Akka committed
1
2
3
4
5
6
package emu.grasscutter.game.activity;

import com.esotericsoftware.reflectasm.ConstructorAccess;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.DataLoader;
import emu.grasscutter.data.GameData;
Melledy's avatar
Melledy committed
7
import emu.grasscutter.game.player.BasePlayerManager;
Akka's avatar
Akka committed
8
import emu.grasscutter.game.player.Player;
Akka's avatar
Akka committed
9
import emu.grasscutter.game.props.ActivityType;
Akka's avatar
Akka committed
10
11
12
13
14
15
16
17
18
19
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.util.*;
import java.util.concurrent.ConcurrentHashMap;

@Getter
Melledy's avatar
Melledy committed
20
public class ActivityManager extends BasePlayerManager {
Akka's avatar
Akka committed
21
22
23
24
25
26
27
28
29
30
    private static final Map<Integer, ActivityConfigItem> activityConfigItemMap;
    private final Map<Integer, PlayerActivityData> playerActivityDataMap;

    static {
        activityConfigItemMap = new HashMap<>();
        loadActivityConfigData();
    }

    private static void loadActivityConfigData() {
        // scan activity type handler & watcher type
Akka's avatar
Akka committed
31
32
        var activityHandlerTypeMap = new HashMap<ActivityType, ConstructorAccess<?>>();
        var activityWatcherTypeMap = new HashMap<WatcherTriggerType, ConstructorAccess<?>>();
Akka's avatar
Akka committed
33
34
35
        var reflections = new Reflections(ActivityManager.class.getPackage().getName());

        reflections.getSubTypesOf(ActivityHandler.class).forEach(item -> {
Akka's avatar
Akka committed
36
            var typeName = item.getAnnotation(GameActivity.class);
Akka's avatar
Akka committed
37
38
39
            activityHandlerTypeMap.put(typeName.value(), ConstructorAccess.get(item));
        });
        reflections.getSubTypesOf(ActivityWatcher.class).forEach(item -> {
Akka's avatar
Akka committed
40
41
            var typeName = item.getAnnotation(ActivityWatcherType.class);
            activityWatcherTypeMap.put(typeName.value(), ConstructorAccess.get(item));
Akka's avatar
Akka committed
42
43
        });

44
45
        try {
            DataLoader.loadList("ActivityConfig.json", ActivityConfigItem.class).forEach(item -> {
Akka's avatar
Akka committed
46
                var activityData = GameData.getActivityDataMap().get(item.getActivityId());
github-actions's avatar
github-actions committed
47
                if (activityData == null) {
Akka's avatar
Akka committed
48
49
50
                    Grasscutter.getLogger().warn("activity {} not exist.", item.getActivityId());
                    return;
                }
Akka's avatar
Akka committed
51
52
                var activityHandlerType = activityHandlerTypeMap.get(ActivityType.getTypeByName(activityData.getActivityType()));
                ActivityHandler activityHandler;
Akka's avatar
Akka committed
53

github-actions's avatar
github-actions committed
54
                if (activityHandlerType != null) {
Akka's avatar
Akka committed
55
                    activityHandler = (ActivityHandler) activityHandlerType.newInstance();
github-actions's avatar
github-actions committed
56
                }else {
Akka's avatar
Akka committed
57
                    activityHandler = new DefaultActivityHandler();
Akka's avatar
Akka committed
58
                }
Akka's avatar
Akka committed
59
60
61
                activityHandler.setActivityConfigItem(item);
                activityHandler.initWatchers(activityWatcherTypeMap);
                item.setActivityHandler(activityHandler);
Akka's avatar
Akka committed
62
63
64
65

                activityConfigItemMap.putIfAbsent(item.getActivityId(), item);
            });

Akka's avatar
Akka committed
66
            Grasscutter.getLogger().info("Enable {} activities.", activityConfigItemMap.size());
Akka's avatar
Akka committed
67
        } catch (Exception e) {
Akka's avatar
Akka committed
68
            Grasscutter.getLogger().error("Unable to load activities config.", e);
Akka's avatar
Akka committed
69
70
71
72
        }

    }

github-actions's avatar
github-actions committed
73
    public ActivityManager(Player player) {
Melledy's avatar
Melledy committed
74
        super(player);
Akka's avatar
Akka committed
75

Akka's avatar
Akka committed
76
77
78
79
        playerActivityDataMap = new ConcurrentHashMap<>();
        // load data for player
        activityConfigItemMap.values().forEach(item -> {
            var data = PlayerActivityData.getByPlayer(player, item.getActivityId());
github-actions's avatar
github-actions committed
80
            if (data == null) {
Akka's avatar
Akka committed
81
82
83
84
85
86
87
                data = item.getActivityHandler().initPlayerActivityData(player);
                data.save();
            }
            data.setPlayer(player);
            data.setActivityHandler(item.getActivityHandler());
            playerActivityDataMap.put(item.getActivityId(), data);
        });
Akka's avatar
Akka committed
88

Akka's avatar
Akka committed
89
        player.sendPacket(new PacketActivityScheduleInfoNotify(activityConfigItemMap.values()));
Akka's avatar
Akka committed
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
    }

    /**
     * trigger activity watcher
     */
    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));
    }
Akka's avatar
Akka committed
109

github-actions's avatar
github-actions committed
110
    public ActivityInfoOuterClass.ActivityInfo getInfoProtoByActivityId(int activityId) {
Akka's avatar
Akka committed
111
112
113
114
115
116
        var activityHandler = activityConfigItemMap.get(activityId).getActivityHandler();
        var activityData = playerActivityDataMap.get(activityId);

        return activityHandler.toProto(activityData);
    }

github-actions's avatar
github-actions committed
117
    public Optional<ActivityHandler> getActivityHandler(ActivityType type) {
Akka's avatar
Akka committed
118
119
120
121
122
123
        return activityConfigItemMap.values().stream()
            .map(ActivityConfigItem::getActivityHandler)
            .filter(x -> type == x.getClass().getAnnotation(GameActivity.class).value())
            .findFirst();
    }

github-actions's avatar
github-actions committed
124
    public <T extends ActivityHandler> Optional<T> getActivityHandlerAs(ActivityType type, Class<T> clazz) {
Akka's avatar
Akka committed
125
126
127
        return getActivityHandler(type).map(x -> (T)x);
    }

github-actions's avatar
github-actions committed
128
    public Optional<Integer> getActivityIdByActivityType(ActivityType type) {
Akka's avatar
Akka committed
129
130
131
132
        return getActivityHandler(type)
            .map(ActivityHandler::getActivityConfigItem)
            .map(ActivityConfigItem::getActivityId);
    }
github-actions's avatar
github-actions committed
133
    public Optional<PlayerActivityData> getPlayerActivityDataByActivityType(ActivityType type) {
Akka's avatar
Akka committed
134
135
136
        return getActivityIdByActivityType(type)
            .map(playerActivityDataMap::get);
    }
github-actions's avatar
github-actions committed
137
    public Optional<ActivityInfoOuterClass.ActivityInfo> getInfoProtoByActivityType(ActivityType type) {
Akka's avatar
Akka committed
138
139
140
141
       return getActivityIdByActivityType(type)
           .map(this::getInfoProtoByActivityId);
    }

Akka's avatar
Akka committed
142
}