3636import java .io .InputStreamReader ;
3737import java .net .URLConnection ;
3838import java .util .Comparator ;
39- import java .util .regex .Matcher ;
40- import java .util .regex .Pattern ;
4139
4240public class VoxelSniperPlugin extends JavaPlugin {
4341
4442 private static final long HOURS_TO_TICKS = 72000L ;
45- private static final Pattern VERSION_ENTRY_PATTERN = Pattern .compile ("\\ {[^{}]*\" name\" \\ s*:\\ s*\" ([^\" ]+)\" [^{}]*}" );
4643
4744 private static final Logger LOGGER = LogManagerCompat .getLogger ();
4845 public static VoxelSniperPlugin plugin ;
@@ -285,12 +282,7 @@ private double updateCheck(double currentVersion) {
285282 }
286283 }
287284
288- Matcher matcher = VERSION_ENTRY_PATTERN .matcher (response );
289- String latestVersionName = null ;
290- while (matcher .find ()) {
291- latestVersionName = matcher .group (1 );
292- }
293-
285+ String latestVersionName = findLatestVersionName (response .toString ());
294286 if (latestVersionName == null ) {
295287 LOGGER .warn ("No files found, or Feed URL is bad." );
296288 return currentVersion ;
@@ -303,4 +295,76 @@ private double updateCheck(double currentVersion) {
303295 return Double .NaN ;
304296 }
305297
298+ private static String findLatestVersionName (String response ) {
299+ int depth = 0 ;
300+ boolean inString = false ;
301+ boolean escaping = false ;
302+ int lastObjectStart = -1 ;
303+ int lastObjectEnd = -1 ;
304+
305+ for (int index = 0 ; index < response .length (); index ++) {
306+ char character = response .charAt (index );
307+ if (escaping ) {
308+ escaping = false ;
309+ continue ;
310+ }
311+ if (inString && character == '\\' ) {
312+ escaping = true ;
313+ continue ;
314+ }
315+ if (character == '"' ) {
316+ inString = !inString ;
317+ continue ;
318+ }
319+ if (inString ) {
320+ continue ;
321+ }
322+ if (character == '{' ) {
323+ if (depth == 0 ) {
324+ lastObjectStart = index ;
325+ }
326+ depth ++;
327+ } else if (character == '}' ) {
328+ depth --;
329+ if (depth == 0 && lastObjectStart != -1 ) {
330+ lastObjectEnd = index + 1 ;
331+ }
332+ }
333+ }
334+ if (lastObjectStart == -1 || lastObjectEnd == -1 ) {
335+ return null ;
336+ }
337+
338+ String lastObject = response .substring (lastObjectStart , lastObjectEnd );
339+ int nameKeyStart = lastObject .indexOf ("\" name\" " );
340+ if (nameKeyStart == -1 ) {
341+ return null ;
342+ }
343+ int colonIndex = lastObject .indexOf (':' , nameKeyStart + 6 );
344+ if (colonIndex == -1 ) {
345+ return null ;
346+ }
347+ int valueStart = lastObject .indexOf ('"' , colonIndex + 1 );
348+ if (valueStart == -1 ) {
349+ return null ;
350+ }
351+ int valueEnd = valueStart + 1 ;
352+ boolean valueEscaping = false ;
353+ while (valueEnd < lastObject .length ()) {
354+ char character = lastObject .charAt (valueEnd );
355+ if (valueEscaping ) {
356+ valueEscaping = false ;
357+ } else if (character == '\\' ) {
358+ valueEscaping = true ;
359+ } else if (character == '"' ) {
360+ break ;
361+ }
362+ valueEnd ++;
363+ }
364+ if (valueEnd >= lastObject .length ()) {
365+ return null ;
366+ }
367+ return lastObject .substring (valueStart + 1 , valueEnd );
368+ }
369+
306370}
0 commit comments