1
mirror of https://github.com/StarWishsama/Slimefun4.git synced 2024-09-19 19:25:48 +00:00

[ci skip] Reduced mojang.com connection errors

This commit is contained in:
TheBusyBiscuit 2020-05-16 12:04:19 +02:00
parent d181d54245
commit c4012fe697
5 changed files with 107 additions and 16 deletions

View File

@ -45,6 +45,7 @@
* Fixed Organic Food/Fertilizer not being recognized
* Fixed #1883
* Fixed #1829
* Fixed some mojang.com connection errors
## Release Candidate 11 (25 Apr 2020)

View File

@ -37,6 +37,8 @@ class ContributionsConnector extends GitHubConnector {
private final String role;
private final int page;
private boolean finished = false;
ContributionsConnector(GitHubService github, String prefix, int page, String repository, String role) {
super(github, repository);
@ -45,8 +47,18 @@ class ContributionsConnector extends GitHubConnector {
this.role = role;
}
/**
* This returns whether this {@link ContributionsConnector} has finished its task.
*
* @return Whether it is finished
*/
public boolean hasFinished() {
return finished;
}
@Override
public void onSuccess(JsonElement element) {
finished = true;
if (element.isJsonArray()) {
computeContributors(element.getAsJsonArray());
}
@ -55,6 +67,11 @@ class ContributionsConnector extends GitHubConnector {
}
}
@Override
public void onFailure() {
finished = true;
}
@Override
public String getFileName() {
return prefix + "_contributors";
@ -74,9 +91,7 @@ class ContributionsConnector extends GitHubConnector {
String profile = object.get("html_url").getAsString();
if (!blacklist.contains(name)) {
Contributor contributor = github.getContributors().computeIfAbsent(name, key -> new Contributor(aliases.getOrDefault(name, name), profile));
contributor.setContribution(role, commits);
github.addContributor(aliases.getOrDefault(name, name), profile, role, commits);
}
}
}

View File

@ -4,6 +4,8 @@ import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@ -27,9 +29,11 @@ public class Contributor {
private final String githubUsername;
private final String minecraftUsername;
private final String profileLink;
private final ConcurrentMap<String, Integer> contributions = new ConcurrentHashMap<>();
private final ComputedOptional<String> headTexture = ComputedOptional.createNew();
private Optional<UUID> uuid = Optional.empty();
private boolean locked = false;
public Contributor(String username, String profile) {
@ -96,6 +100,26 @@ public class Contributor {
return contributions.getOrDefault(role, 0);
}
/**
* This method sets the {@link UUID} for this {@link Contributor}.
*
* @param uuid
* The {@link UUID} for this {@link Contributor}
*/
public void setUniqueId(UUID uuid) {
this.uuid = uuid == null ? Optional.empty() : Optional.of(uuid);
}
/**
* This returns the {@link UUID} for this {@link Contributor}.
* This {@link UUID} may be loaded from a cache.
*
* @return The {@link UUID} of this {@link Contributor}
*/
public Optional<UUID> getUniqueId() {
return uuid;
}
/**
* Returns this Creator's head texture.
* If no texture could be found, or it hasn't been pulled yet,

View File

@ -1,14 +1,18 @@
package io.github.thebusybiscuit.slimefun4.core.services.github;
import java.io.File;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import io.github.thebusybiscuit.cscorelib2.config.Config;
import io.github.thebusybiscuit.slimefun4.core.services.localization.Translators;
import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
@ -26,6 +30,7 @@ public class GitHubService {
private final String repository;
private final Set<GitHubConnector> connectors;
private final ConcurrentMap<String, Contributor> contributors;
private final Config uuidCache = new Config("plugins/Slimefun/cache/github/uuids.yml");
private boolean logging = false;
@ -64,9 +69,16 @@ public class GitHubService {
private void addContributor(String name, String role) {
Contributor contributor = new Contributor(name);
contributor.setContribution(role, 0);
contributor.setUniqueId(uuidCache.getUUID(name));
contributors.put(name, contributor);
}
protected void addContributor(String name, String profile, String role, int commits) {
Contributor contributor = contributors.computeIfAbsent(name, key -> new Contributor(name, profile));
contributor.setContribution(role, commits);
contributor.setUniqueId(uuidCache.getUUID(name));
}
private void loadConnectors(boolean logging) {
this.logging = logging;
addDefaultContributors();
@ -179,4 +191,20 @@ public class GitHubService {
public LocalDateTime getLastUpdate() {
return lastUpdate;
}
/**
* This will store the {@link UUID} of all {@link Contributor Contributors} in memory
* in a {@link File} to save requests the next time we iterate over them.
*/
protected void saveUUIDCache() {
for (Contributor contributor : contributors.values()) {
Optional<UUID> uuid = contributor.getUniqueId();
if (uuid.isPresent()) {
uuidCache.setValue(contributor.getName(), uuid.get());
}
}
uuidCache.save();
}
}

View File

@ -26,7 +26,7 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
*/
class GitHubTask implements Runnable {
private static final int MAX_REQUESTS_PER_MINUTE = 10;
private static final int MAX_REQUESTS_PER_MINUTE = 16;
private final GitHubService gitHubService;
@ -54,8 +54,9 @@ class GitHubTask implements Runnable {
contributor.setTexture(skins.get(contributor.getMinecraftName()));
}
else {
contributor.setTexture(grabTexture(skins, contributor.getMinecraftName()));
count++;
contributor.setTexture(grabTexture(skins, contributor));
count += contributor.getUniqueId().isPresent() ? 1 : 2;
if (count >= MAX_REQUESTS_PER_MINUTE) {
break;
@ -71,32 +72,54 @@ class GitHubTask implements Runnable {
Slimefun.getLogger().log(Level.WARNING, "Attempted to connect to mojang.com, got this response: {0}: {1}", new Object[] { x.getClass().getSimpleName(), x.getMessage() });
Slimefun.getLogger().log(Level.WARNING, "This usually means mojang.com is down or started to rate-limit this connection, this is not an error message!");
// Retry after 4 minutes if it was rate-limiting
// Retry after 5 minutes if it was rate-limiting
if (x.getMessage().contains("429")) {
Bukkit.getScheduler().runTaskLaterAsynchronously(SlimefunPlugin.instance, this::grabTextures, 4 * 60 * 20L);
Bukkit.getScheduler().runTaskLaterAsynchronously(SlimefunPlugin.instance, this::grabTextures, 5 * 60 * 20L);
}
return;
count = 0;
break;
}
catch (TooManyRequestsException x) {
Slimefun.getLogger().log(Level.WARNING, "Received a rate-limit from mojang.com, retrying in 2 minutes");
Bukkit.getScheduler().runTaskLaterAsynchronously(SlimefunPlugin.instance, this::grabTextures, 2 * 60 * 20L);
return;
Slimefun.getLogger().log(Level.WARNING, "Received a rate-limit from mojang.com, retrying in 4 minutes");
Bukkit.getScheduler().runTaskLaterAsynchronously(SlimefunPlugin.instance, this::grabTextures, 4 * 60 * 20L);
count = 0;
break;
}
}
}
if (count >= MAX_REQUESTS_PER_MINUTE) {
// Slow down API requests and wait a minute after more than x requests were made
Bukkit.getScheduler().runTaskLaterAsynchronously(SlimefunPlugin.instance, this::grabTextures, 60 * 20L);
Bukkit.getScheduler().runTaskLaterAsynchronously(SlimefunPlugin.instance, this::grabTextures, 2 * 60 * 20L);
}
for (GitHubConnector connector : gitHubService.getConnectors()) {
if (connector instanceof ContributionsConnector && !((ContributionsConnector) connector).hasFinished()) {
return;
}
}
// We only wanna save this if all Connectors finished already
// This will run multiple times but thats okay, this way we get as much data as possible stored
gitHubService.saveUUIDCache();
}
private String grabTexture(Map<String, String> skins, String username) throws TooManyRequestsException, IOException {
Optional<UUID> uuid = MinecraftAccount.getUUID(username);
private String grabTexture(Map<String, String> skins, Contributor contributor) throws TooManyRequestsException, IOException {
Optional<UUID> uuid = contributor.getUniqueId();
if (!uuid.isPresent()) {
uuid = MinecraftAccount.getUUID(contributor.getMinecraftName());
if (uuid.isPresent()) {
contributor.setUniqueId(uuid.get());
}
}
if (uuid.isPresent()) {
Optional<String> skin = MinecraftAccount.getSkin(uuid.get());
skins.put(username, skin.orElse(""));
skins.put(contributor.getMinecraftName(), skin.orElse(""));
return skin.orElse(null);
}
else {