    001package net.minecraft.profiler;
    002
    003import cpw.mods.fml.relauncher.Side;
    004import cpw.mods.fml.relauncher.SideOnly;
    005import java.lang.management.ManagementFactory;
    006import java.lang.management.RuntimeMXBean;
    007import java.net.MalformedURLException;
    008import java.net.URL;
    009import java.util.HashMap;
    010import java.util.Iterator;
    011import java.util.LinkedHashMap;
    012import java.util.List;
    013import java.util.Map;
    014import java.util.Timer;
    015import java.util.UUID;
    016import java.util.Map.Entry;
    017
    018public class PlayerUsageSnooper
    019{
    020    /** String map for report data */
    021    private Map dataMap = new HashMap();
    022    private final String uniqueID = UUID.randomUUID().toString();
    023
    024    /** URL of the server to send the report to */
    025    private final URL serverUrl;
    026    private final IPlayerUsage playerStatsCollector;
    027
    028    /** set to fire the snooperThread every 15 mins */
    029    private final Timer threadTrigger = new Timer("Snooper Timer", true);
    030    private final Object syncLock = new Object();
    031    private final long field_98224_g = System.currentTimeMillis();
    032    private boolean isRunning = false;
    033
    034    /** incremented on every getSelfCounterFor */
    035    private int selfCounter = 0;
    036
    037    public PlayerUsageSnooper(String par1Str, IPlayerUsage par2IPlayerUsage)
    038    {
    039        try
    040        {
    041            this.serverUrl = new URL("http://snoop.minecraft.net/" + par1Str + "?version=" + 1);
    042        }
    043        catch (MalformedURLException malformedurlexception)
    044        {
    045            throw new IllegalArgumentException();
    046        }
    047
    048        this.playerStatsCollector = par2IPlayerUsage;
    049    }
    050
    051    /**
    052     * Note issuing start multiple times is not an error.
    053     */
    054    public void startSnooper()
    055    {
    056        if (!this.isRunning)
    057        {
    058            this.isRunning = true;
    059            this.addBaseDataToSnooper();
    060            this.threadTrigger.schedule(new PlayerUsageSnooperThread(this), 0L, 900000L);
    061        }
    062    }
    063
    064    private void addBaseDataToSnooper()
    065    {
    066        this.addJvmArgsToSnooper();
    067        this.addData("snooper_token", this.uniqueID);
    068        this.addData("os_name", System.getProperty("os.name"));
    069        this.addData("os_version", System.getProperty("os.version"));
    070        this.addData("os_architecture", System.getProperty("os.arch"));
    071        this.addData("java_version", System.getProperty("java.version"));
    072        this.addData("version", "1.5.1");
    073        this.playerStatsCollector.addServerTypeToSnooper(this);
    074    }
    075
    076    private void addJvmArgsToSnooper()
    077    {
    078        RuntimeMXBean runtimemxbean = ManagementFactory.getRuntimeMXBean();
    079        List list = runtimemxbean.getInputArguments();
    080        int i = 0;
    081        Iterator iterator = list.iterator();
    082
    083        while (iterator.hasNext())
    084        {
    085            String s = (String)iterator.next();
    086
    087            if (s.startsWith("-X"))
    088            {
    089                this.addData("jvm_arg[" + i++ + "]", s);
    090            }
    091        }
    092
    093        this.addData("jvm_args", Integer.valueOf(i));
    094    }
    095
    096    public void addMemoryStatsToSnooper()
    097    {
    098        this.addData("memory_total", Long.valueOf(Runtime.getRuntime().totalMemory()));
    099        this.addData("memory_max", Long.valueOf(Runtime.getRuntime().maxMemory()));
    100        this.addData("memory_free", Long.valueOf(Runtime.getRuntime().freeMemory()));
    101        this.addData("cpu_cores", Integer.valueOf(Runtime.getRuntime().availableProcessors()));
    102        this.addData("run_time", Long.valueOf((System.currentTimeMillis() - this.field_98224_g) / 60L * 1000L));
    103        this.playerStatsCollector.addServerStatsToSnooper(this);
    104    }
    105
    106    /**
    107     * Adds information to the report
    108     */
    109    public void addData(String par1Str, Object par2Obj)
    110    {
    111        Object object1 = this.syncLock;
    112
    113        synchronized (this.syncLock)
    114        {
    115            this.dataMap.put(par1Str, par2Obj);
    116        }
    117    }
    118
    119    @SideOnly(Side.CLIENT)
    120    public Map getCurrentStats()
    121    {
    122        LinkedHashMap linkedhashmap = new LinkedHashMap();
    123        Object object = this.syncLock;
    124
    125        synchronized (this.syncLock)
    126        {
    127            this.addMemoryStatsToSnooper();
    128            Iterator iterator = this.dataMap.entrySet().iterator();
    129
    130            while (iterator.hasNext())
    131            {
    132                Entry entry = (Entry)iterator.next();
    133                linkedhashmap.put(entry.getKey(), entry.getValue().toString());
    134            }
    135
    136            return linkedhashmap;
    137        }
    138    }
    139
    140    public boolean isSnooperRunning()
    141    {
    142        return this.isRunning;
    143    }
    144
    145    public void stopSnooper()
    146    {
    147        this.threadTrigger.cancel();
    148    }
    149
    150    @SideOnly(Side.CLIENT)
    151    public String getUniqueID()
    152    {
    153        return this.uniqueID;
    154    }
    155
    156    static IPlayerUsage getStatsCollectorFor(PlayerUsageSnooper par0PlayerUsageSnooper)
    157    {
    158        return par0PlayerUsageSnooper.playerStatsCollector;
    159    }
    160
    161    static Object getSyncLockFor(PlayerUsageSnooper par0PlayerUsageSnooper)
    162    {
    163        return par0PlayerUsageSnooper.syncLock;
    164    }
    165
    166    static Map getDataMapFor(PlayerUsageSnooper par0PlayerUsageSnooper)
    167    {
    168        return par0PlayerUsageSnooper.dataMap;
    169    }
    170
    171    /**
    172     * returns a value indicating how many times this function has been run on the snooper
    173     */
    174    static int getSelfCounterFor(PlayerUsageSnooper par0PlayerUsageSnooper)
    175    {
    176        return par0PlayerUsageSnooper.selfCounter++;
    177    }
    178
    179    static URL getServerUrlFor(PlayerUsageSnooper par0PlayerUsageSnooper)
    180    {
    181        return par0PlayerUsageSnooper.serverUrl;
    182    }
    183}