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 boolean isRunning = false;
032
033    /** incremented on every getSelfCounterFor */
034    private int selfCounter = 0;
035
036    public PlayerUsageSnooper(String par1Str, IPlayerUsage par2IPlayerUsage)
037    {
038        try
039        {
040            this.serverUrl = new URL("http://snoop.minecraft.net/" + par1Str + "?version=" + 1);
041        }
042        catch (MalformedURLException var4)
043        {
044            throw new IllegalArgumentException();
045        }
046
047        this.playerStatsCollector = par2IPlayerUsage;
048    }
049
050    /**
051     * Note issuing start multiple times is not an error.
052     */
053    public void startSnooper()
054    {
055        if (!this.isRunning)
056        {
057            this.isRunning = true;
058            this.addBaseDataToSnooper();
059            this.threadTrigger.schedule(new PlayerUsageSnooperThread(this), 0L, 900000L);
060        }
061    }
062
063    private void addBaseDataToSnooper()
064    {
065        this.addJvmArgsToSnooper();
066        this.addData("snooper_token", this.uniqueID);
067        this.addData("os_name", System.getProperty("os.name"));
068        this.addData("os_version", System.getProperty("os.version"));
069        this.addData("os_architecture", System.getProperty("os.arch"));
070        this.addData("java_version", System.getProperty("java.version"));
071        this.addData("version", "1.4.7");
072        this.playerStatsCollector.addServerTypeToSnooper(this);
073    }
074
075    private void addJvmArgsToSnooper()
076    {
077        RuntimeMXBean var1 = ManagementFactory.getRuntimeMXBean();
078        List var2 = var1.getInputArguments();
079        int var3 = 0;
080        Iterator var4 = var2.iterator();
081
082        while (var4.hasNext())
083        {
084            String var5 = (String)var4.next();
085
086            if (var5.startsWith("-X"))
087            {
088                this.addData("jvm_arg[" + var3++ + "]", var5);
089            }
090        }
091
092        this.addData("jvm_args", Integer.valueOf(var3));
093    }
094
095    public void addMemoryStatsToSnooper()
096    {
097        this.addData("memory_total", Long.valueOf(Runtime.getRuntime().totalMemory()));
098        this.addData("memory_max", Long.valueOf(Runtime.getRuntime().maxMemory()));
099        this.addData("memory_free", Long.valueOf(Runtime.getRuntime().freeMemory()));
100        this.addData("cpu_cores", Integer.valueOf(Runtime.getRuntime().availableProcessors()));
101        this.playerStatsCollector.addServerStatsToSnooper(this);
102    }
103
104    /**
105     * Adds information to the report
106     */
107    public void addData(String par1Str, Object par2Obj)
108    {
109        Object var3 = this.syncLock;
110
111        synchronized (this.syncLock)
112        {
113            this.dataMap.put(par1Str, par2Obj);
114        }
115    }
116
117    @SideOnly(Side.CLIENT)
118    public Map getCurrentStats()
119    {
120        LinkedHashMap var1 = new LinkedHashMap();
121        Object var2 = this.syncLock;
122
123        synchronized (this.syncLock)
124        {
125            this.addMemoryStatsToSnooper();
126            Iterator var3 = this.dataMap.entrySet().iterator();
127
128            while (var3.hasNext())
129            {
130                Entry var4 = (Entry)var3.next();
131                var1.put(var4.getKey(), var4.getValue().toString());
132            }
133
134            return var1;
135        }
136    }
137
138    public boolean isSnooperRunning()
139    {
140        return this.isRunning;
141    }
142
143    public void stopSnooper()
144    {
145        this.threadTrigger.cancel();
146    }
147
148    @SideOnly(Side.CLIENT)
149    public String getUniqueID()
150    {
151        return this.uniqueID;
152    }
153
154    static IPlayerUsage getStatsCollectorFor(PlayerUsageSnooper par0PlayerUsageSnooper)
155    {
156        return par0PlayerUsageSnooper.playerStatsCollector;
157    }
158
159    static Object getSyncLockFor(PlayerUsageSnooper par0PlayerUsageSnooper)
160    {
161        return par0PlayerUsageSnooper.syncLock;
162    }
163
164    static Map getDataMapFor(PlayerUsageSnooper par0PlayerUsageSnooper)
165    {
166        return par0PlayerUsageSnooper.dataMap;
167    }
168
169    /**
170     * returns a value indicating how many times this function has been run on the snooper
171     */
172    static int getSelfCounterFor(PlayerUsageSnooper par0PlayerUsageSnooper)
173    {
174        return par0PlayerUsageSnooper.selfCounter++;
175    }
176
177    static URL getServerUrlFor(PlayerUsageSnooper par0PlayerUsageSnooper)
178    {
179        return par0PlayerUsageSnooper.serverUrl;
180    }
181}