59 private static final Map<String, ItemDefinition> itemByName =
new HashMap<>();
61 private NpcDropsParser() {
62 super(generateTables());
65 private static LinkedList<WikiTable> generateTables() {
69 if (definition ==
null || definition.
getName() ==
null || definition.
getName().equals(
"null") || itemByName.containsKey(definition.
getName())) {
72 itemByName.put(definition.
getName(), definition);
75 LinkedListMultimap<String, NpcDefinition> byName = LinkedListMultimap.create();
80 if (definition ==
null || definition.
getName() ==
null || definition.
getName().equals(
"null")) {
84 if (!definition.isAttackable()) {
88 if (NpcDropManager.NPC_DROPS.containsKey(definition.
getId())) {
92 byName.put(definition.
getName(), definition);
95 LinkedList<WikiTable>
tables =
new LinkedList<>();
98 for (Map.Entry<String, Collection<NpcDefinition>> entry : byName.asMap().entrySet()) {
99 String name = entry.getKey();
100 name = name.replaceAll(
" ",
"_");
101 int idx = name.indexOf(
"(");
103 name = name.substring(0, idx);
104 tables.add(
new NpcDropTable(
WIKI_LINK.concat(name), entry.getValue()));
110 protected void finish() {
111 JsonArray array =
new JsonArray();
113 array.addAll(table.getTable());
118 public static void main(String[] args)
throws InterruptedException {
119 NpcDropsParser parser =
new NpcDropsParser();
123 private static class NpcDropTable
extends WikiTable {
124 private final Collection<NpcDefinition> definitions;
126 NpcDropTable(String link, Collection<NpcDefinition> definitions) {
128 this.definitions = definitions;
132 protected void parseDocument(Document document) {
133 Elements dropTable = document.select(
".wikitable.sortable.dropstable");
134 Elements td = dropTable.select(
"td");
135 Iterator<Element> iterator = td.iterator();
137 List<DropItem> drops =
new LinkedList<>();
138 boolean rareDropTable =
false;
140 while (iterator.hasNext()) {
142 String name = iterator.next().text();
143 String amount = iterator.next().text().replaceAll(
",",
"");
144 String rarity = iterator.next().text().toLowerCase();
147 if (!itemByName.containsKey(name)) {
148 log(
"missing item: " + name);
149 if (name.contains(
"Rare drop table")) {
150 rareDropTable =
true;
155 if (amount.contains(
"Unknown")) {
156 log(
"unknown drop amount: " + name);
163 int notedIndex = amount.indexOf(
"(noted)");
164 if (notedIndex > -1) {
165 amount = amount.substring(0, notedIndex - 1).trim();
166 id = itemByName.get(name).getNotedId();
168 id = itemByName.get(name).getId();
172 if (rarity.startsWith(
"very rare")) {
173 rate = DropRarity.VERY_RARE;
174 }
else if (rarity.startsWith(
"rare")) {
175 rate = DropRarity.RARE;
176 }
else if (rarity.startsWith(
"uncommon")) {
177 rate = DropRarity.UNCOMMON;
178 }
else if (rarity.startsWith(
"common")) {
179 rate = DropRarity.COMMON;
180 }
else if (rarity.startsWith(
"always")) {
181 rate = DropRarity.ALWAYS;
183 log(
"unknown drop rarity: " + rarity);
187 if (amount.contains(
";")) {
188 String[] amounts = amount.split(
"; ");
189 for (String s : amounts) {
190 int hyphen = s.indexOf(
"–");
192 min = Integer.valueOf(s.substring(0, hyphen));
193 max = Integer.valueOf(s.substring(hyphen + 1));
195 min = max = Integer.valueOf(s);
197 drops.add(
new DropItem(
id, min, max, rate));
200 int hyphen = amount.indexOf(
"–");
202 min = Integer.valueOf(amount.substring(0, hyphen));
203 max = Integer.valueOf(amount.substring(hyphen + 1));
205 min = max = Integer.valueOf(amount);
207 drops.add(
new DropItem(
id, min, max, rate));
209 }
catch (Exception e) {
214 if (drops.isEmpty()) {
218 JsonObject
object =
new JsonObject();
219 JsonArray array =
new JsonArray();
222 array.add(definition.getId());
225 drops.sort(Comparator.comparing(drop -> drop.rarity));
227 object.add(
"ids", array);
228 object.addProperty(
"rare_table", rareDropTable);
229 object.add(
"drops", buildDropItemTables(drops));
233 private static JsonArray buildDropItemTables(Collection<DropItem> drops) {
234 JsonArray items =
new JsonArray();
236 for (DropItem item : drops) {
237 JsonObject dropItem =
new JsonObject();
239 dropItem.addProperty(
"id", item.id);
240 dropItem.addProperty(
"minimum", item.min);
241 dropItem.addProperty(
"maximum", item.max);
242 dropItem.addProperty(
"type", item.rarity.name());
249 private void log(String message) {
250 String name = ((
NpcDefinition) definitions.toArray()[0]).getName();
251 System.out.println(
"[name=" + name +
"] -- " + message);
256 private static class DropItem {
257 private final int id;
258 private final int min;
259 private final int max;
260 private final DropRarity rarity;
262 private DropItem(
int id,
int min,
int max, DropRarity rarity) {
266 this.rarity = rarity;
270 public int hashCode() {
271 return Objects.hash(
id, min, max, rarity);
275 public boolean equals(Object obj) {
276 if (obj ==
this)
return true;
277 if (obj instanceof DropItem) {
278 DropItem other = (DropItem) obj;
279 return other.id ==
id && other.min == min && other.max == max && other.rarity.equals(rarity);
285private enum DropRarity {