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}