Skip to content

Commit a00cdfe

Browse files
committed
[U] Spiget: Modify download latest
1 parent be9ea86 commit a00cdfe

File tree

4 files changed

+86
-32
lines changed

4 files changed

+86
-32
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.hydev.mcpm;
2+
3+
import com.fasterxml.jackson.databind.ObjectMapper;
4+
5+
import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;
6+
import static com.fasterxml.jackson.databind.SerializationFeature.INDENT_OUTPUT;
7+
8+
/**
9+
* Global constants
10+
*
11+
* @author Azalea (https://github.com/hykilpikonna)
12+
* @since 2022-10-03
13+
*/
14+
public class Constants
15+
{
16+
public static final ObjectMapper JACKSON = new ObjectMapper()
17+
.configure(FAIL_ON_UNKNOWN_PROPERTIES, false).enable(INDENT_OUTPUT);
18+
}

src/main/java/org/hydev/mcpm/server/crawlers/SpigetCrawler.java

Lines changed: 65 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
import com.fasterxml.jackson.databind.node.ArrayNode;
66
import org.apache.hc.client5.http.HttpResponseException;
77
import org.apache.hc.client5.http.fluent.Request;
8+
import org.hydev.mcpm.client.models.PluginYml;
89
import org.hydev.mcpm.server.crawlers.spiget.SpigetResource;
10+
import org.hydev.mcpm.utils.PluginJarFile;
11+
import org.hydev.mcpm.utils.StoredHashMap;
12+
import org.hydev.mcpm.utils.TemporaryDir;
913

1014
import java.io.File;
1115
import java.io.IOException;
@@ -17,6 +21,7 @@
1721
import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;
1822
import static com.fasterxml.jackson.databind.SerializationFeature.INDENT_OUTPUT;
1923
import static java.lang.String.format;
24+
import static org.hydev.mcpm.Constants.JACKSON;
2025
import static org.hydev.mcpm.utils.GeneralUtils.makeUrl;
2126
import static org.hydev.mcpm.utils.GeneralUtils.safeSleep;
2227

@@ -28,17 +33,16 @@
2833
*/
2934
public class SpigetCrawler
3035
{
31-
public static final ObjectMapper JACKSON = new ObjectMapper()
32-
.configure(FAIL_ON_UNKNOWN_PROPERTIES, false).enable(INDENT_OUTPUT);;
33-
3436
private final String spiget = "https://api.spiget.org/v2";
3537
private final String userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36";
3638
private final long mtDelay = 1000;
3739
private final File dataDir;
40+
private final StoredHashMap<Long, String> blacklist;
3841

3942
public SpigetCrawler(File dataDir)
4043
{
4144
this.dataDir = dataDir;
45+
this.blacklist = new StoredHashMap<>(new File(dataDir, "crawler/spiget/blacklist.json"));
4246
}
4347

4448
/**
@@ -152,43 +156,82 @@ private File getTemporaryDownloadPath(SpigetResource res)
152156
*/
153157
private File getLatestPath(SpigetResource res)
154158
{
155-
return new File(dataDir, format("pkgs/spiget/%s/%s/release.jar", res.name(), res.id()));
159+
return new File(dataDir, format("pkgs/spiget/%s/%s/release.jar", res.id(), res.version().id()));
156160
}
157161

158162
/**
159-
* Download the latest version of a plugin if not present
163+
* Check update for a plugin
160164
*
161165
* @param res Resource
162166
*/
163-
private void downloadLatest(SpigetResource res)
167+
private void checkUpdate(SpigetResource res)
164168
{
165-
var fp = getTemporaryDownloadPath(res);
166-
if (fp.isFile() || res.external()) return;
169+
// Plugin is in the blacklist, skip
170+
if (blacklist.containsKey(res.id())) return;
171+
172+
// Latest version already exists in local fs, skip
173+
var fp = getLatestPath(res);
174+
if (fp.isFile()) return;
175+
176+
// Resource is marked as external, we can't download it
177+
if (res.external()) return;
167178

168-
// Make request
179+
// Try downloading the file
180+
System.out.printf("Trying to download %s: %s\n", res.id(), res.name());
169181
var url = makeUrl(format(spiget + "/resources/%s/download", res.id()));
170182

171-
try
183+
try (var tmp = new TemporaryDir())
172184
{
185+
var tmpFile = new File(tmp.path, "tmp.jar");
186+
173187
// Write bytes
188+
// TODO: Maybe we can do this without tmp files, like read zip file content from byte array
189+
var jarBytes = Request.get(url).addHeader("User-Agent", userAgent).execute().returnContent().asBytes();
190+
Files.write(tmpFile.toPath(), jarBytes);
191+
192+
// Try to read plugin.yml from it
193+
String metaStr;
194+
try (var plugin = new PluginJarFile(tmpFile))
195+
{
196+
metaStr = plugin.readString("plugin.yml");
197+
}
198+
catch (Exception e)
199+
{
200+
// Cannot read plugin.yml, that means it's not a standard plugin, add to blacklist
201+
System.out.printf("Cannot read plugin.yml (%s: %s)\n", res.id(), res.name());
202+
blacklist.put(res.id(), "Cannot read plugin.yml");
203+
return;
204+
}
205+
206+
// Success, write to file
174207
fp.getParentFile().mkdirs();
175-
Files.write(fp.toPath(), Request.get(url).addHeader("User-Agent", userAgent).execute()
176-
.returnContent().asBytes());
208+
209+
// Write meta to plugin.yml
210+
Files.writeString(new File(fp.getParentFile(), "plugin.yml").toPath(), metaStr);
211+
212+
// Write jar to release.jar
213+
Files.write(fp.toPath(), jarBytes);
177214

178215
System.out.printf("Downloaded (%s) %s latest version jar\n", res.id(), res.name());
179216
}
180217
catch (HttpResponseException e)
181218
{
182219
// Not found
183-
if (e.getMessage().contains("404")) return;
220+
if (e.getMessage().contains("404"))
221+
blacklist.put(res.id(), "HTTP 404: Not found");
222+
184223
// "External resource cannot be downloaded"
185-
if (e.getMessage().contains("400")) return;
224+
else if (e.getMessage().contains("400"))
225+
blacklist.put(res.id(), "HTTP 400: Probably external resource");
226+
186227
// Blocked by cloudflare
187-
if (e.getMessage().contains("520")) return;
228+
else if (e.getMessage().contains("520"))
229+
blacklist.put(res.id(), "HTTP 520: External site, blocked by CloudFlare");
230+
188231
// This happens when the server has an error (e.g. when a plugin doesn't have files to download)
189-
if (e.getMessage().contains("502")) return;
232+
//else if (e.getMessage().contains("502")) return;
233+
190234
System.out.println("Error when downloading " + url + " " + e.getMessage());
191-
//e.printStackTrace();
192235
}
193236
catch (IOException e)
194237
{
@@ -201,15 +244,16 @@ public static void main(String[] args)
201244
{
202245
var crawler = new SpigetCrawler(new File(".mcpm"));
203246
var res = crawler.crawlAllResources(false).stream()
204-
.filter(it -> it.downloads() > 1000 && !it.external()).toList();
247+
.filter(it -> it.downloads() > 100 && !it.external()).toList();
205248

206249
System.out.println(res.size());
207250

208-
res.stream().filter(it -> !crawler.getTemporaryDownloadPath(it).isFile()).parallel().forEach(it ->
251+
// TODO: Parallelize this. Currently causes ConcurrentModificationException with StoredHashMap
252+
res.stream().filter(it -> !crawler.getLatestPath(it).isFile()).forEach(it ->
209253
{
210-
crawler.downloadLatest(it);
254+
crawler.checkUpdate(it);
211255

212-
safeSleep(crawler.mtDelay);
256+
//safeSleep(crawler.mtDelay);
213257
});
214258
}
215259
}

src/main/java/org/hydev/mcpm/server/crawlers/spiget/SpigetResource.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
* @param updateDate Update timestamp in ms
1818
* @param downloads Number of downloads
1919
* @param existenceStatus Existence status, IDK what this means
20+
* @param version Latest version ID and UUID
2021
*
2122
* @author Azalea (https://github.com/hykilpikonna)
2223
* @since 2022-09-27
@@ -32,7 +33,8 @@ public record SpigetResource(
3233
long releaseDate,
3334
long updateDate,
3435
long downloads,
35-
long existenceStatus
36+
long existenceStatus,
37+
SpigetVersion version
3638
)
3739
{
3840
}

src/main/java/org/hydev/mcpm/server/crawlers/spiget/SpigetVersion.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,13 @@
33
/**
44
* Spiget Version POJO for endpoint api.spiget.org/v2/resources/{resource_id}/versions
55
*
6-
* @param downloads Number of downloads
7-
* @param url Link to download
8-
* @param name Version name (e.g. 1.0)
9-
* @param releaseDate Release timestamp in milliseconds
10-
* @param resource Resource ID (should be the same for all versions of one resource)
116
* @param uuid Unique ID for the version
127
* @param id Numeric ID of the version
138
*
149
* @author Azalea (https://github.com/hykilpikonna)
1510
* @since 2022-09-28
1611
*/
1712
public record SpigetVersion(
18-
int downloads,
19-
String url,
20-
String name,
21-
long releaseDate,
22-
long resource,
2313
String uuid,
2414
long id
2515
)

0 commit comments

Comments
 (0)