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}