001    package net.minecraft.profiler;
002    
003    import cpw.mods.fml.relauncher.Side;
004    import cpw.mods.fml.relauncher.SideOnly;
005    import java.lang.management.ManagementFactory;
006    import java.lang.management.RuntimeMXBean;
007    import java.net.MalformedURLException;
008    import java.net.URL;
009    import java.util.HashMap;
010    import java.util.Iterator;
011    import java.util.LinkedHashMap;
012    import java.util.List;
013    import java.util.Map;
014    import java.util.Timer;
015    import java.util.UUID;
016    import java.util.Map.Entry;
017    
018    public 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    }