[Resource] Get Item ID From String

Discussion in 'Resources' started by krazytraynz, Feb 16, 2014.

Thread Status:
Not open for further replies.
  1. Offline

    krazytraynz

    After an hour or so of research and trial and error, I figured out a pretty compact way (21 lines) to get the ID of an item through a string. It uses JSoup so it's pretty much useless unless there's a way to implement JSoup into a plugin, in which case I learned something new, and you're welcome :p I think this is pretty cool either way.

    Code:java
    1. package com.github.KrazyTraynz;
    2.  
    3.  
    4. import org.jsoup.Jsoup;
    5. import org.jsoup.nodes.Document;
    6. import org.jsoup.nodes.Element;
    7.  
    8. import java.io.IOException;
    9. import java.util.Map;
    10. import java.util.TreeMap;
    11.  
    12. public class StringID {
    13.  
    14. Map<String, String> ids = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
    15.  
    16. public void setPairs(){
    17. Document doc = null;
    18.  
    19. try{
    20. doc = Jsoup.connect("[url]http://minecraft-ids.grahamedgecombe.com[/url]").get(); //REMOVE THE URL TAGS
    21. }catch(IOException ex){
    22. ex.printStackTrace();
    23. }
    24.  
    25. for(Element table : doc.select("table")){
    26. for(Element body : table.select("tbody")){
    27. for(Element row : body.select("tr")){
    28. String name = row.select("td").get(2).text();
    29. String ID = row.select("td").get(0).text();
    30.  
    31. ids.put(name, ID);
    32. }
    33. }
    34. }
    35. }
    36.  
    37. public String getID(String s){
    38. if(ids.containsKey(s)){
    39. return ids.get(s);
    40. }
    41. return "";
    42. }
    43.  
    44. public Object getName(String s){
    45. for(Map.Entry entry : ids.entrySet()){
    46. if(s.equals(entry.getValue())){
    47. return entry.getKey();
    48. }
    49. }
    50. return "";
    51. }
    52. }
    53.  


    Call setPairs() in your onEnable(), and getID() and getName() can be called anywhere else. Both of the "get" methods do exactly what you think they do. getID() is case-insensitive for convenience, so don't worry about capitalization.
     
  2. Offline

    Georgeto

    Calling this Method from the Server Thread is deadly...
     
  3. Offline

    filoghost

    A better method would be to download all that stuff and put them in a hashmap. You can code it to output the final code. @krazytrynz
     
  4. Offline

    krazytraynz

    Georgeto
    Never really put into consideration what this could do to a server :oops:

    filoghost
    So just modify the method to put everything into a HashMap, and create a separate method to call it?
     
  5. Offline

    filoghost

    Exactly. So you don't have to check the website every time :) A list of formatted materials would be very useful.
     
  6. Offline

    krazytraynz

    Updated to be thread-safe, thanks filoghost :D
     
  7. Offline

    grahamedgecombe

    The site now offers the list in JSON and TSV format. Using one of those, instead of scraping the HTML, would make this code much more robust in the face of any markup changes I make to the HTML in the future.

    To parse the TSV you could do something along these lines in setPairs() instead:

    Code:
    URL url = new URL("http://minecraft-ids.grahamedgecombe.com/items.tsv");
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), StandardCharsets.UTF_8))) {
        String row;
        while ((row = reader.readLine()) != null) {
            row = row.trim();
            if (row.isEmpty()) /* skip blank lines */
                continue;
     
            String[] cols = row.split("\t");
            String name = cols[2];
            String id = cols[0];
            String metadata = cols[1];
            String idAndMetadata = metadata.equals("0") ? id : (id + ":" + metadata);
            ids.put(name, idAndMetadata);
        }
    }
    
     
    desht likes this.
  8. Offline

    Garris0n

    Or you could use the server files.
     
  9. Offline

    DreadKyller

    I don't understand why this is even needed. The Material class already has the item id's stored and has a method to retrieve a Material by name.

    Code:
    int id= Material.getMaterial(name.toUpperCase()).getId();
    getId() is depricated however it still works, and isn't the only method to get the id from the material, so why reference a site and parse it to obtain values that already exist?
     
  10. Offline

    SirFaizdat

    That method is pretty bad. It's not very user friendly and doesn't recognize a lot of common item names.
     
  11. Offline

    xTrollxDudex

    krazytraynz
    This class isn't thread safe... Your HashMap would need to be switched to a ConcurrentHashMap
     
  12. Offline

    Phasesaber

  13. Offline

    Necrodoom

    That's because its not an alias database.
    If you want to add name aliases to items, use internal list, the website it self doesn't contain that many names, so its also quite pointless for this.
    Besides, the original purpose of this is to get item ID, which is perfectly covered by material enum. krazytraynz you do realise newbies will try to use it because its in the resource section? Hence it needs to be coded as well as possible, and using external libraries for something that can be done with material enum is quite pointless.
     
Thread Status:
Not open for further replies.

Share This Page