サイトから抜き出してdropsqlを作成

Go down

サイトから抜き出してdropsqlを作成

投稿 by 構築さん on 2014-05-31, 18:01

toolsにdropfetcherclass

を作成

Code:
package tools.dropfetcher;

import client.inventory.MapleInventoryType;
import constants.GameConstants;


/**
* @author Simon
* @author Sonic - only a few small changes
*/
public class DropEntry {

private final int version;
private final int item_id;
private final int monster_id;
private final int chance;
private int mindrop;
private int maxdrop;
private final boolean isBoss;

/**
* Creates a new drop entry object. Duh.
*
* @param item_id
* The item ID of the drop.
* @param monster_id
* The monster ID of the dropper.
* @param isBoss
* Is this monster a boss monster?
* @param version
* What version is the drop from. Does almost nothing, actually.
*/
public DropEntry(final int item_id, final int monster_id, final boolean isBoss, final int version) {
this.item_id = item_id;
this.monster_id = monster_id;
mindrop = 1;
maxdrop = 1;
chance = calculateChance(item_id, monster_id);
this.version = version;
this.isBoss = isBoss;
}

/**
* Calculates the drop chance for a given Item ID. The chances are
* estimated, and I have no idea how to get the real ones. Deal with it.
* Thing is, this is probably outdated with v120. So if anyone wants to
* update it - have fun.
*
* @param item_id
* The Item ID to calculate the drop chance for.
* @return The drop chance for the given Item ID.
*/
private int calculateChance(final int item_id, final int monsterId) {
MapleInventoryType mit = GameConstants.getInventoryType(item_id);
int number = (item_id / 1000) % 1000;
switch (mit) {
case EQUIP:
if (isBoss) {
return 300000;
}
return 7000;
case USE:
if (isBoss) {
mindrop = 1;
maxdrop = 4;
}
switch (number) {
case 0: // Normal potions
mindrop = 1;
if (version > 98) {
maxdrop = 5;
}
return 100000;
case 1: // watermelons, pills, speed potions, etc
case 2: // same thing
return 50000;
case 3: // advanced potions from crafting (should not drop)
case 4: // same thing
case 11: // poison mushroom
case 28: // cool items
case 30: // return scrolls
case 46: // gallant scrolls
return 0;
case 10: // strange potions like apples, eggs
case 12: // drakes blood, sap of ancient tree (rare use)
case 20: // salad, fried chicken, dews
case 22: // air bubbles and stuff. ALSO nependeath honey but oh well
case 50: // antidotes and stuff
case 290: // mastery books
return 10000;
case 40:
case 41:
case 43:
case 44:
case 48: // pet scrolls
case 100: // summon bags
case 101: // summon bags
case 102: // summon bags
case 109: // summon bags
case 120: // pet food
case 211: // cliffs special potion
case 240: // rings
case 270: // pheromone, additional weird stuff
case 310: // teleport rock
case 320: // weird drops
case 390: // weird
case 430: // quiz things? compass?
case 440: // jukebox
case 460: // magnifying glass
case 470: // golden hammer
case 490: // crystanol
case 500: // sp reset
return 0;
case 47: // tablets from dragon rider
return 250000;
case 49: // clean slats, potential scroll, ees
case 70: // throwing stars
case 210: // rare monster piece drops
case 330: // bullets
return 1000;
case 60: // bow arrows
case 61: // crossbow arrows
mindrop = 10;
maxdrop = 50;
return 20000;
case 213: // boss transfrom
return 300000;
case 280: // skill books
return 200000;
case 381: // monster book things
case 382:
case 383:
case 384:
case 385:
case 386:
case 387:
case 388:
return 20000;
case 510: // recipes
case 511:
case 512:
return 10000;
default:
return 0;

}
case ETC:
switch (number) {
case 0: // monster pieces
return 400000;
case 4: // crystal ores
case 130: // simulators
case 131: // manuals
return 10000;
case 30: // game pieces
return 50000;
case 32: // misc items
return 250000;
default:
return 10000;
}
default:
return 10000;
}
}

/**
* Builds a query string from the data.
*
* @return The query string.
*/
public String getQuerySegment() {
StringBuilder sb = new StringBuilder();
sb.append("(");
sb.append(monster_id);
sb.append(", ");
sb.append(item_id);
sb.append(", ");
sb.append(mindrop); // Minimum amount of items to drop at once
sb.append(", ");
sb.append(maxdrop); // Maximum amount of items to drop at once
sb.append(", ");
sb.append(0); // Quest ID. Too lazy to even look at that
sb.append(", ");
sb.append(chance); // Drop chance. Again, estimated
sb.append(")");
return sb.toString();
}
}

Code:
package tools.dropfetcher;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.Scanner;


/**
* @author Simon
* @author Sonic
*/
public class DropFetcher {

/**
* @param args
* The command line arguments.
*/
private static ArrayList<DropEntry> drop_entries = new ArrayList<DropEntry>();
private static final String BASE_URL = "http://maplearchive.com/";
private static final String MONSTER_PAGE = "mob-wp.php";
private static int NumberOfPages = 157; // As for v120, but it's probably going to change so idk
private static int CurrentPage = 1; // Hurr durr
public static final int VERSION = 120;
private static int MonstersDone = 0; // Total monsters done
private static int MonstersWithDrops = 0; // Monsters that have drop
private static int MonstersWithoutDrops = 0; // Monsters that have no drops
private static int Errors = 0; // How many times I failed with this script

/**
* Crawls the mob data page with the given URL, fetching the drop data.
*
* @param url
* The URL of the page to crawl.
*/
private static void crawlPage(final String url) { // Recursive method bitches
try {
URL page = new URL(url);
InputStream is = page.openStream();
Scanner s = new Scanner(is);
String temp_data = "";
while (s.hasNext()) {
temp_data += s.nextLine() + "\n";
}
s.close();
is.close();
while (temp_data.contains("class=\"mobImage\"")) {
try {
String monster_section;
if (!temp_data.contains("<div>")) {
monster_section = getStringBetween(temp_data, "class=\"mobImage\"", "<div>"); // Who cares, it works
} else {
monster_section = getStringBetween(temp_data, "class=\"mobImage\"", "<div>");
}
parseMonsterSection(monster_section);
temp_data = trimUntil(temp_data, "<div>");
if (temp_data == null) {
break;
}
} catch (StringIndexOutOfBoundsException ex) {
System.out.println("Whoops! Something went wrong. Skipping this one...");
Errors++;
break;
}
}
System.out.println("Finished crawling page " + CurrentPage + ".");
if (CurrentPage % 10 == 0) {
System.out.println();
System.out.println("Status so far:");
System.out.println("Monsters: " + MonstersDone + " || Monsters with drops: " + MonstersWithDrops + " || Monsters without drops: " + MonstersWithoutDrops + " || Items: " + drop_entries.size() + " || Errors: " + Errors);
System.out.println();
}
} catch (MalformedURLException mue) {
System.out.println("Error parsing URL: " + url);
Errors++;
return;
} catch (IOException ioe) {
System.out.println("Error reading from URL: " + ioe.getLocalizedMessage());
Errors++;
return;
}
}

/**
* Builds an SQL file to insert the fetched data to a database.
*/
public static void dumpQuery() {
String filename = "MapleArchive-Drops-v" + VERSION + ".sql";
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
File output = new File(filename);
BufferedWriter bw = new BufferedWriter(new FileWriter(output));
PrintWriter pw = new PrintWriter(bw);
StringBuilder sb = new StringBuilder();
pw.write("/*\r\n * This file was built using the MapleArchive drop fetcher script by Sonic/Simon. \r\n * Creation date: " + sdf.format(Calendar.getInstance().getTime()) + "\r\n * MapleArchive Database version: GlobalMS v" + VERSION + "\r\n * \r\n * -Drop chances are estimated as they cannot be obtained!-\r\n */\r\n\r\n");
pw.write("TRUNCATE TABLE `drop_data`;\r\n");
pw.write("INSERT INTO `drop_data` (`dropperid`, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance`) VALUES ");
for (Iterator<DropEntry> i = drop_entries.iterator(); i.hasNext();) {
DropEntry de = i.next();
pw.write(de.getQuerySegment());
if (i.hasNext()) {
pw.write(", \r\n");
}
}
pw.write(sb.toString());
pw.close();
bw.close();
} catch (IOException ioe) {
System.out.println("Error writing to file: " + ioe.getLocalizedMessage());
}
}

/**
* Returns the string lying between the two specified strings.
*
* @param line
* The string to parse
* @param start
* The first string
* @param end
* The last string
* @return The string between the two specified strings
*/
public static String getStringBetween(final String line, final String start, final String end) {
int start_offset = line.indexOf(start) + start.length();
return line.substring(start_offset, line.substring(start_offset).indexOf(end) + start_offset);
}

public static void main(final String[] args) {
long startTime = System.currentTimeMillis();
System.out.println("MapleArchive Drop Data Fetcher\nOriginal script by Simon --- Modified version by Sonic");
System.out.println("---------------------------------------");
System.out.println("Here we go!");
System.out.println();
for (CurrentPage = 1; CurrentPage <NumberOfPages>"));
drop_entries.add(new DropEntry(ItemId, MonsterId, isBoss, VERSION));
if (temp_data.contains("javascript:return ")) {
temp_data = trimUntil(temp_data, "javascript:return ");
} else { // Abusive shit and stuff
return;
}
}
}

/**
* Parses a monster section from a given data string.
*
* @param html_data
* The string containing the HTML data to parse from.
*/
private static void parseMonsterSection(final String html_data) {
MonstersDone++;
int MonsterId = Integer.parseInt(getStringBetween(html_data, "alt=\"Mob:", "\" />")); // Will it blend? ;-)
boolean isBoss = false;
String BossString = getStringBetween(html_data, "<tr><td>Boss:</td><td>", "</td></tr>");
if (BossString.equalsIgnoreCase("No")) {
isBoss = false;
} else if (BossString.equalsIgnoreCase("Yes")) {
isBoss = true;
}

if (getStringBetween(html_data, "<td class=\"tdDrops\" ", "</td>").contains("<ul><li>None/Unknown</li></ul>")) {
http://System.out.println("Whoops!");
MonstersWithoutDrops++;
return;
}
// Parse Equipment drops
parseItemSection(getStringBetween(html_data, ">Equipment</a>", "</ul></li>"), MonsterId, isBoss);
// Parse Potion drops
parseItemSection(getStringBetween(html_data, ">Potion</a>", "</ul></li>"), MonsterId, isBoss);
// Parse Food drops
parseItemSection(getStringBetween(html_data, ">Food</a>", "</ul></li>"), MonsterId, isBoss);
// Parse Arrow drops
parseItemSection(getStringBetween(html_data, ">Arrows</a>", "</ul></li>"), MonsterId, isBoss);
// Parse Misc. Box (The hell is that? :O)
parseItemSection(getStringBetween(html_data, ">Misc. Box</a>", "</ul></li>"), MonsterId, isBoss);
// Parse Familiar drops
parseItemSection(getStringBetween(html_data, ">Familiar</a>", "</ul></li>"), MonsterId, isBoss);
// Parse Setup drops
parseItemSection(getStringBetween(html_data, ">Setup</a>", "</ul></li>"), MonsterId, isBoss);
// Parse ETC drops
parseItemSection(getStringBetween(html_data, ">Etc</a>", "</ul></li>"), MonsterId, isBoss);

MonstersWithDrops++;
}

/**
* Trims a string until the first occurrence of the provided substring,
* including the substring itself.
*
* @param line
* The string to trim.
* @param until
* The substring to stop the trimming after.
* @return The trimmed string.
*/
public static String trimUntil(final String line, final String until) {
int until_pos = line.indexOf(until);
if (until_pos == -1) {
return null;
} else {
return line.substring(until_pos + until.length());
}
}
}

Batを作成

Code:
@echo off
@title MapleArchive Drop Fetcher

set CLASSPATH=.;dist\*
java -Dnet.sf.odinms.wzpath=wz\ tools.dropfetcher.DropFetcher
pause
avatar
構築さん
Admin

Posts : 193
Join date : 2014/05/29

http://maplescience.forumjap.com

トップに戻る Go down

トップに戻る


 
Permissions in this forum:
返信投稿: 不可