/
RequirementChecker.java
185 lines (157 loc) · 7.73 KB
/
RequirementChecker.java
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
package net.aufdemrand.denizen.scripts.requirements;
import net.aufdemrand.denizen.exceptions.RequirementCheckException;
import net.aufdemrand.denizencore.objects.aH;
import net.aufdemrand.denizencore.objects.dScript;
import net.aufdemrand.denizen.tags.BukkitTagContext;
import net.aufdemrand.denizen.utilities.DenizenAPI;
import net.aufdemrand.denizen.utilities.debugging.dB;
import org.bukkit.ChatColor;
import java.util.List;
import net.aufdemrand.denizencore.tags.TagManager;
/**
* This class implements requirement checking for scripts.
*
* @author aufdemrand
*/
public class RequirementChecker {
public RequirementChecker() {
}
/**
* Checks a RequirementsContext with Requirements from the RequirementsRegistry.
*
* @param context the context to check against
* @return true if the list meets the requirements and context set
*
*/
public boolean check(RequirementsContext context) {
//
// Requirement node "NONE"? No requirements in the LIST? No need to
// continue, return true.
//
if (context.mode.getMode() == RequirementsMode.Mode.NONE || context.list.isEmpty())
return true;
//
// Actual requirements that need checking, alert the debugger
//
dB.echoDebug(context.getScriptContainer(), ChatColor.YELLOW + "CHECK! Now checking '" + context.container.getName() + "'");
dB.echoDebug(context.getScriptContainer(), "Requirement mode: '" + context.mode.getMode().toString() + "'");
// Set up checks for requirement mode 'FIRST AND ANY #'
boolean firstReqMet = false;
boolean firstReqChecked = false;
// Counter for keeping track of met requirements
int numberMet = 0;
// Check all requirements
for (String reqEntry : context.list) {
boolean negativeRequirement = false;
//
// Check if this is a Negative Requirement. Negative requirements start
// with a... negative sign :)
//
if (reqEntry.startsWith("-")) {
negativeRequirement = true;
reqEntry = reqEntry.substring(1);
}
//
// Replace tags and build arguments
//
List<String> argumentList = TagManager.fillArguments(aH.buildArgs(reqEntry),
new BukkitTagContext(context.player, context.npc, false, null, dB.shouldDebug(context.getScriptContainer()), new dScript(context.getScriptContainer())));
String reqString = argumentList.get(0).toUpperCase();
//
// Evaluate the requirement
//
// <--[requirement]
// @Name ValueOf
// @Syntax valueof [<tag>]
// @Required 1
// @Stable stable
// @Short Checks if the tag is true.
//
// @Description
// Checks if a specified tag or value returns 'true'.
//
// @Usage
// Check if a simple tag is true.
// - valueof <player.is_player>
//
// @Usage
// Check a comparable (See <@link language comparable> for more information.)
// - valueof <player.health.is[LESS].than[10]>
// -->
if (reqString.equalsIgnoreCase("valueof")) {
String arg = argumentList.get(1);
if (arg.equalsIgnoreCase("true")) {
if (!negativeRequirement) {
dB.echoApproval("Checking 'VALUEOF " + arg + "... requirement met!");
numberMet++;
} else
dB.echoApproval("Checking '-VALUEOF " + arg + "...requirement not met!");
} else {
if (!negativeRequirement)
dB.echoApproval("Checking 'VALUEOF " + arg + "...requirement not met!");
else {
dB.echoApproval("Checking '-VALUEOF " + arg + "...requirement met!");// Not met!
numberMet++;
}
}
} else
// Check requirement with RequirementRegistry
if (DenizenAPI.getCurrentInstance().getRequirementRegistry().list().containsKey(reqString)) {
AbstractRequirement requirement = DenizenAPI.getCurrentInstance().getRequirementRegistry().get(reqString);
// Remove command name from arguments
argumentList.remove(0);
try {
// Check if # of required args are met
int numArguments = argumentList.isEmpty() ? 0 : argumentList.size();
int neededArguments = requirement.requirementOptions.REQUIRED_ARGS;
if ((numArguments == 0 && neededArguments > 0) ||
numArguments < neededArguments) {
throw new RequirementCheckException("Not enough arguments (" + numArguments + " / " + neededArguments + ")");
}
// Check the Requirement
if (requirement.check(context, argumentList) != negativeRequirement) {
// Check first requirement for mode 'FIRST AND ANY #'
if (!firstReqChecked) {
firstReqMet = true;
firstReqChecked = true;
}
numberMet++;
dB.echoApproval("Checked '" + requirement.getName() + "'" + " ...requirement met!");
} else {
if (!firstReqChecked) {
firstReqMet = false;
firstReqChecked = true;
}
dB.echoApproval("Checked '" + requirement.getName() + "'" + " ...requirement not met!");
}
} catch (Throwable e) {
if (e instanceof RequirementCheckException) {
String msg = e.getMessage().isEmpty() || e == null ? "No Error message defined!" : e.getMessage();
dB.echoError("Woah! Invalid arguments were specified: " + msg);
dB.echoError("Usage: " + requirement.getUsageHint());
} else {
dB.echoError("Woah! An exception has been called " + (requirement != null ? "for Requirement '" + requirement.getName() + "'" : "") + "!");
dB.echoError(e);
}
}
}
// If the requirement is not registered with the Requirement Registry
else {
dB.echoError("Requirement '" + reqEntry.split(" ")[0] + "' not found! Check that the requirement is installed!");
}
}
// Check numberMet with mode-type
// ALL mode
if (context.mode.getMode() == RequirementsMode.Mode.ALL && numberMet == context.list.size()) return true;
// ANY # mode
else if (context.mode.getMode() == RequirementsMode.Mode.ANY_NUM) {
return (numberMet >= context.mode.modeInt);
}
// FIRST AND ANY # mode
else if (context.mode.getMode() == RequirementsMode.Mode.FIRST_AND_ANY_NUM) {
return firstReqMet && (numberMet <= context.mode.modeInt);
}
// Nothing met, return FALSE
return false;
}
}