summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/bukkit/craftbukkit/help/SimpleHelpMap.java
blob: 01eb5533cc1586865dd54dc0f29ba14070c72331 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package org.bukkit.craftbukkit.help;

import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.MultipleCommandAlias;
import org.bukkit.command.PluginCommand;
import org.bukkit.command.defaults.VanillaCommand;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.help.*;

import java.util.*;

/**
 * Standard implementation of {@link HelpMap} for CraftBukkit servers.
 */
public class SimpleHelpMap implements HelpMap {
    
    private HelpTopic defaultTopic;
    private Map<String, HelpTopic> helpTopics;
    private Map<Class, HelpTopicFactory> topicFactoryMap;

    public SimpleHelpMap() {
        helpTopics = new TreeMap<String, HelpTopic>(new HelpTopicComparator()); // Using a TreeMap for its explicit sorting on key
        defaultTopic = new IndexHelpTopic("Index", null, null, Collections2.filter(helpTopics.values(), Predicates.not(Predicates.instanceOf(CommandAliasHelpTopic.class))));
        topicFactoryMap = new HashMap<Class, HelpTopicFactory>();

        registerHelpTopicFactory(MultipleCommandAlias.class, new MultipleCommandAliasHelpTopicFactory());
    }
    
    public synchronized HelpTopic getHelpTopic(String topicName) {
        if (topicName.equals("")) {
            return defaultTopic;
        }

        if (helpTopics.containsKey(topicName)) {
            return helpTopics.get(topicName);
        }

        return null;
    }

    public synchronized void addTopic(HelpTopic topic) {
        // Existing topics take priority
        if (!helpTopics.containsKey(topic.getName())) {
            helpTopics.put(topic.getName(), topic);
        }
    }

    public synchronized void clear() {
        helpTopics.clear();
    }

    /**
     * Reads the general topics from help.yml and adds them to the help index.
     * @param server A reference to the server.
     */
    public synchronized void initializeGeneralTopics(CraftServer server) {
        HelpYamlReader reader = new HelpYamlReader(server);

        // Initialize general help topics from the help.yml file
        for (HelpTopic topic : reader.getGeneralTopics()) {
            addTopic(topic);
        }
    }

    /**
     * Processes all the commands registered in the server and creates help topics for them.
     * @param server A reference to the server.
     */
    @SuppressWarnings("unchecked")
    public synchronized void initializeCommands(CraftServer server) {
        // ** Load topics from highest to lowest priority order **

        // Initialize help topics from the server's command map
        outer: for (Command command : server.getCommandMap().getCommands()) {
            for (Class c : topicFactoryMap.keySet()) {
                if (c.isAssignableFrom(command.getClass())) {
                    addTopic(topicFactoryMap.get(c).createTopic(command));
                    continue outer;
                }
                if (command instanceof PluginCommand && c.isAssignableFrom(((PluginCommand)command).getExecutor().getClass())) {
                    addTopic(topicFactoryMap.get(c).createTopic(command));
                    continue outer;
                }
            }
            addTopic(new GenericCommandHelpTopic(command));
        }
        
        // Initialize command alias help topics
        for (Command command : server.getCommandMap().getCommands()) {
            for (String alias : command.getAliases()) {
                addTopic(new CommandAliasHelpTopic(alias, command.getLabel(), this));
            }
        }

        // Initialize help topics from the server's fallback commands
        for (VanillaCommand command : server.getCommandMap().getFallbackCommands()) {
            addTopic(new GenericCommandHelpTopic(command));
        }

        // Add alias sub-index
        addTopic(new IndexHelpTopic("Aliases", "Lists command aliases", null, Collections2.filter(helpTopics.values(), Predicates.instanceOf(CommandAliasHelpTopic.class))));

        // Amend help topics from the help.yml file
        HelpYamlReader reader = new HelpYamlReader(server);
        for (HelpTopicAmendment amendment : reader.getTopicAmendments()) {
            if (helpTopics.containsKey(amendment.getTopicName())) {
                helpTopics.get(amendment.getTopicName()).amendTopic(amendment.getShortText(), amendment.getFullText());
                if (amendment.getPermission() != null) {
                    helpTopics.get(amendment.getTopicName()).amendCanSee(amendment.getPermission());
                }
            }
        }
    }

    public void registerHelpTopicFactory(Class commandClass, HelpTopicFactory factory) {
        if (!Command.class.isAssignableFrom(commandClass) && !CommandExecutor.class.isAssignableFrom(commandClass)) {
            throw new IllegalArgumentException("commandClass must implement either Command or CommandExecutor!");
        }
        topicFactoryMap.put(commandClass, factory);
    }
}