17 + | import com.google.common.io.Resources; |
18 + | import java.io.BufferedReader; |
19 + | import java.io.IOException; |
20 + | import java.net.URL; |
21 + | import java.net.URLEncoder; |
22 + | import java.util.HashSet; |
23 + | import java.util.Set; |
24 + | import java.util.concurrent.locks.ReentrantLock; |
25 + | import java.util.logging.Level; |
26 + | import java.util.logging.Logger; |
27 + | import org.json.simple.JSONObject; |
28 + | import org.json.simple.parser.JSONParser; |
29 + | import org.json.simple.parser.ParseException; |
144 + | |
145 + | private final ReentrantLock versionLock = new ReentrantLock(); |
146 + | private boolean hasVersion = false; |
147 + | private String versionMessage = null; |
148 + | private final Set<CommandSender> versionWaiters = new HashSet<CommandSender>(); |
149 + | private boolean versionTaskStarted = false; |
150 + | private long lastCheck = 0; |
151 + | |
152 + | private void sendVersion(CommandSender sender) { |
153 + | if (hasVersion) { |
154 + | if (System.currentTimeMillis() - lastCheck > 21600000) { |
155 + | lastCheck = System.currentTimeMillis(); |
156 + | hasVersion = false; |
157 + | } else { |
158 + | sender.sendMessage(versionMessage); |
159 + | return; |
160 + | } |
161 + | } |
162 + | versionLock.lock(); |
163 + | try { |
164 + | if (hasVersion) { |
165 + | sender.sendMessage(versionMessage); |
166 + | return; |
167 + | } |
168 + | versionWaiters.add(sender); |
169 + | sender.sendMessage("Checking version, please wait..."); |
170 + | if (!versionTaskStarted) { |
171 + | versionTaskStarted = true; |
172 + | new Thread(new Runnable() { |
173 + | |
174 + | @Override |
175 + | public void run() { |
176 + | obtainVersion(); |
177 + | } |
178 + | }).start(); |
179 + | } |
180 + | } finally { |
181 + | versionLock.unlock(); |
182 + | } |
183 + | } |
184 + | |
185 + | private void obtainVersion() { |
186 + | String version = Bukkit.getVersion(); |
187 + | if (version == null) version = "Custom"; |
188 + | if (version.startsWith("git-Spigot-")) { |
189 + | String[] parts = version.substring("git-Spigot-".length()).split("-"); |
190 + | int cbVersions = getDistance("craftbukkit", parts[0]); |
191 + | int spigotVersions = getDistance("spigot", parts[1]); |
192 + | if (cbVersions == -1 || spigotVersions == -1) { |
193 + | setVersionMessage("Error obtaining version information"); |
194 + | } else { |
195 + | if (cbVersions != 0 && spigotVersions != 0) { |
196 + | setVersionMessage("You are running the latest version"); |
197 + | } else { |
198 + | setVersionMessage("You are " + (cbVersions + spigotVersions) + " behind"); |
199 + | } |
200 + | } |
201 + | |
202 + | } else if (version.startsWith("git-Bukkit-")) { |
203 + | int cbVersions = getDistance("craftbukkit", version.substring("git-Bukkit-".length())); |
204 + | if (cbVersions == -1) { |
205 + | setVersionMessage("Error obtaining version information"); |
206 + | } else { |
207 + | if (cbVersions != 0) { |
208 + | setVersionMessage("You are running the latest version"); |
209 + | } else { |
210 + | setVersionMessage("You are " + cbVersions + " behind"); |
211 + | } |
212 + | } |
213 + | } else { |
214 + | setVersionMessage("Unknown version, custom build?"); |
215 + | } |
216 + | } |
217 + | |
218 + | private void setVersionMessage(String msg) { |
219 + | lastCheck = System.currentTimeMillis(); |
220 + | versionMessage = msg; |
221 + | versionLock.lock(); |
222 + | try { |
223 + | hasVersion = true; |
224 + | versionTaskStarted = false; |
225 + | for (CommandSender sender : versionWaiters) { |
226 + | sender.sendMessage(versionMessage); |
227 + | } |
228 + | versionWaiters.clear(); |
229 + | } finally { |
230 + | versionLock.unlock(); |
231 + | } |
232 + | } |
233 + | |
234 + | private static int getDistance(String repo, String hash) { |
235 + | try { |
236 + | BufferedReader reader = Resources.asCharSource( |
237 + | new URL("https://hub.spigotmc.org/stash/rest/api/1.0/projects/SPIGOT/repos/" + repo + "/commits?since=" + URLEncoder.encode(hash, "UTF-8") + "&withCounts=true"), |
238 + | Charsets.UTF_8 |
239 + | ).openBufferedStream(); |
240 + | try { |
241 + | JSONObject obj = (JSONObject) new JSONParser().parse(reader); |
242 + | return ((Number) obj.get("totalCount")).intValue(); |
243 + | } catch (ParseException ex) { |
244 + | ex.printStackTrace(); |
245 + | return -1; |
246 + | } finally { |
247 + | reader.close(); |
248 + | } |
249 + | } catch (IOException e) { |
250 + | e.printStackTrace(); |
251 + | return -1; |
252 + | } |
253 + | } |