Usuário:SandroHcBot/Código Fonte/AlchemyTask

De RuneScape Wiki
Ir para: navegação, pesquisa

Checks the alchemy values in pages make sense.

/*--------------------------------------------------------
 * AmauriceBot - RuneScape Wikia update task robot
 * Copyright (c) 2009-2012  Maurice Abraham.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Contributors:
 *   None
 *------------------------------------------------------*/

package amauricebot;

import java.io.IOException;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Description(summary = "Checks the alchemy values in pages make sense.")
public class AlchemyTask implements BotTask
{
    private WikiSession m_wiki = null;
    private HashMap<String,Long> m_values = new HashMap<String,Long>();
    private int m_numReported = 0;

    private final int MAX_REPORTED = 20;
    private final int QUERY_DELAY = 5*1000;
    private final String[] m_checkInfoBoxes = {
                                            "Infobox Item",
                                            "Infobar Summon Scroll",
                                            "Infobar Summon Pouch",
                                            "Infobox Food",
                                            "Infobox Seed"
                                            };
    private final Pattern m_dplPattern = Pattern.compile("\n\\|-"
                                        + "\n\\|\\[\\[([^\\]\\|]+).*"
                                        + "\n\\|(.*)"
                                        + "\n\\|(.*)"
                                        + "\n\\|(.*)");
    private final Pattern m_complexPattern = Pattern.compile("Varies"
                                        + "|Various"
                                        + "|Depends"
                                        + "|See table"
                                        + "|[a-z]{3}\\W"
                                        + "|\\d-\\d"
                                        );

    public AlchemyTask(WikiSession wiki)
    {
        m_wiki = wiki;
    }

    public void perform()
            throws IOException
    {
        loadExchValues();

        for (String infobox : m_checkInfoBoxes)
        {
            checkInfoBoxes(infobox);
        }
    }

    private void loadExchValues()
            throws IOException
    {
        int pagesize = 500;
        for (int i = 0; i < 100; i ++)
        {
            String query = "{{#dpl:"
                        + " | uses = Template:ExchangeItem"
                        + " | namespace = Exchange"
                        + " | offset = " + (i*pagesize)
                        + " | count = " + pagesize
                        + " | include = {ExchangeItem}:Item:Value:Alchable"
                        + " | table = class=wikitable,,Item,Value,Alchable"
                        + " | tablerow = %%,%%,%%"
                        + " }}";

            String text = m_wiki.subst(query);
            if (text == null)
            {
                Utils.log("ERROR: Failed to get alchemy values for Exchange");
                return;
            }

            if (!text.startsWith("{|"))
                break; // no more callers

            Matcher matcher = m_dplPattern.matcher(text);
            while (matcher.find())
            {
                String title = matcher.group(1);
                String name = matcher.group(2);
                if (name.equals(""))
                    name = title;

                long value = Utils.parseNum(matcher.group(3), null, -2);
                if (value < 0)
                {
                    Utils.log("ERROR: Bad value in [[" + title + "]]");
                    continue;
                }
                String alchable = matcher.group(4);
                if (alchable.toLowerCase().equals("no"))
                    value = -1;

                m_values.put(name.toLowerCase(),new Long(value));
            }

            try
            {
                Thread.sleep(QUERY_DELAY);
            }
            catch (Exception ex)
            {
                // ignore exception
            }
        }
    }

    private void checkInfoBoxes(String infobox)
            throws IOException
    {
        int pagesize = 500;
        for (int i = 0; i < 100; i ++)
        {
            if (Utils.excessiveLog() || m_numReported >= MAX_REPORTED)
                break;

            String query = "{{#dpl:"
                        + " | uses = Template:" + infobox
                        + " | namespace ="
                        + " | offset = " + (i*pagesize)
                        + " | count = " + pagesize
                        + " | include = {" + infobox + "}:name:high:low"
                        + " | table = class=wikitable,,Name,High,Low"
                        + " | tablerow = %%,%%,%%"
                        + " }}";
            String text = m_wiki.subst(query);
            if (text == null)
            {
                Utils.log("ERROR: Failed to get calls to " + infobox);
                return;
            }

            if (!text.startsWith("{|"))
                break; // no more callers

            Matcher matcher = m_dplPattern.matcher(text);
            while (matcher.find())
            {
                String title = matcher.group(1);
                String name = matcher.group(2);
                if (name.equals(""))
                    name = title;

                String highStr = matcher.group(3);
                String lowStr = matcher.group(4);

                Long exchValue = null;
                if (name.equals(title) || !title.contains("("))
                    exchValue = m_values.get(name.toLowerCase());

                checkValue(title, name, highStr, lowStr, exchValue);
            }

            try
            {
                Thread.sleep(QUERY_DELAY);
            }
            catch (Exception ex)
            {
                // ignore exception
            }
        }
    }

    private void checkValue(String title, String name,
                            String highStr, String lowStr, Long exchValue)
    {
        // skip muliple alchemy value cases
        if (m_complexPattern.matcher(highStr).find()
                && m_complexPattern.matcher(lowStr).find())
            return;

        long high = (highStr.toLowerCase().equals("no") ? -1 :
                        Utils.parseNum(highStr, null, -2));
        long low = (lowStr.toLowerCase().equals("no") ? -1 :
                        Utils.parseNum(lowStr, null, -2));

        // value -1 = not alchable, value -2 = unknown
        long value = (exchValue != null ? exchValue.longValue() : -2);

        boolean mismatch = false;
        if (high < 0 || low < 0)
        {
            if (high != -1 || low != -1 || value >= 0)
                mismatch = true;
        }
        else
        {
            if (Math.abs(2*high - 3*low) > 2)
                mismatch = true;
            if (value == -1)
                mismatch = true;
            if (value >= 0 && (high != value*3/5 || low != value*2/5))
                mismatch = true;
        }

        if (mismatch && m_numReported < MAX_REPORTED)
        {
            Utils.log("WARNING: Check alchs in [["+title+"|"+name+"]]"
                    + " <small>( " + lowStr + " : " + highStr + " )"
                    + (value == -2 ? "" :
                        (value == -1 ? "exp ( no : no )" :
                            " exp ( "+(value*2/5)+" : "+(value*3/5)+" )"))
                    + "</small>");
            m_numReported ++;
        }
    }
}