mirror of
https://github.com/TuxCoding/FastLogin.git
synced 2025-12-24 23:58:14 +01:00
Compare commits
22 Commits
1.12-kick-
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
327982ddd6 | ||
|
|
65a379c3c2 | ||
|
|
2ff6547552 | ||
|
|
c3233b2c67 | ||
|
|
f86c918a8b | ||
|
|
001cf3237b | ||
|
|
c28c634351 | ||
|
|
4550562465 | ||
|
|
2308d98dcd | ||
|
|
063b6a9405 | ||
|
|
1b45b8d2be | ||
|
|
8be0de4781 | ||
|
|
d06c44041d | ||
|
|
69fa341188 | ||
|
|
e1ba698f28 | ||
|
|
7bf613c8b4 | ||
|
|
1c194280b1 | ||
|
|
5803a34f84 | ||
|
|
86c4f48ec6 | ||
|
|
06e6741493 | ||
|
|
98da5a36da | ||
|
|
3bd9e60783 |
25
.github/release.yml
vendored
Normal file
25
.github/release.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# Configure how the release notes are generated for GitHub releases
|
||||
|
||||
changelog:
|
||||
# List of authors (like bots) and labels to exclude from pull requests
|
||||
exclude:
|
||||
labels:
|
||||
- ignore-for-release
|
||||
categories:
|
||||
- title: 🛠 Breaking Changes
|
||||
labels:
|
||||
- Semver-Major
|
||||
- breaking-change
|
||||
- title: 🎉 Exciting New Features
|
||||
labels:
|
||||
- Semver-Minor
|
||||
- enhancement
|
||||
- title: 🐞 Bugfixes
|
||||
labels:
|
||||
- bug
|
||||
- title: 👒 Dependencies
|
||||
labels:
|
||||
- dependencies
|
||||
- title: Other Changes
|
||||
labels:
|
||||
- "*"
|
||||
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
@@ -46,7 +46,7 @@ jobs:
|
||||
|
||||
# Setup Java
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version-file: '.java-version'
|
||||
|
||||
6
.github/workflows/maven.yml
vendored
6
.github/workflows/maven.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
||||
|
||||
# Setup Java
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version-file: '.java-version'
|
||||
@@ -56,7 +56,7 @@ jobs:
|
||||
|
||||
# Setup Java
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version-file: '.java-version'
|
||||
@@ -64,4 +64,4 @@ jobs:
|
||||
|
||||
- name: Submit Dependency Snapshot
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
uses: advanced-security/maven-dependency-submission-action@v4.0.3
|
||||
uses: advanced-security/maven-dependency-submission-action@v5.0.0
|
||||
|
||||
@@ -32,7 +32,11 @@ Development builds contain the latest changes from the Source-Code. They are ble
|
||||
but also include features, enhancements and bug fixes that are not yet in a released version. If you click on the left
|
||||
side on `Changes`, you can see iterative change sets leading to a specific build.
|
||||
|
||||
You can download them from here: https://ci.codemc.org/job/Games647/job/FastLogin/
|
||||
~~You can download them from here: [CodeMC(Jenkins)](https://ci.codemc.org/job/Games647/job/FastLogin/)~~
|
||||
|
||||
Currently broken due changed usernames. Download it from [here](https://github.com/TuxCoding/FastLogin/releases)
|
||||
|
||||
|
||||
|
||||
***
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@
|
||||
<dependency>
|
||||
<groupId>io.papermc.paper</groupId>
|
||||
<artifactId>paper-api</artifactId>
|
||||
<version>1.20.6-R0.1-SNAPSHOT</version>
|
||||
<version>1.21.6-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
<!-- Use our own newer api version -->
|
||||
<exclusions>
|
||||
@@ -348,6 +348,22 @@
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.zigazajc007</groupId>
|
||||
<artifactId>Passky</artifactId>
|
||||
<version>v3.0.0</version>
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
|
||||
<!-- Exclude dependencies to prevent potential version conflicts-->
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>*</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!--No maven repository :(-->
|
||||
<dependency>
|
||||
<groupId>de.st_ddt.crazy</groupId>
|
||||
@@ -379,7 +395,7 @@
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk18on</artifactId>
|
||||
<version>1.78.1</version>
|
||||
<version>1.80</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.github.games647.fastlogin.core.message.LoginActionMessage;
|
||||
import com.github.games647.fastlogin.core.message.NamespaceKey;
|
||||
import com.google.common.io.ByteArrayDataOutput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import io.papermc.paper.configuration.ServerConfiguration;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -133,6 +134,13 @@ public class BungeeManager {
|
||||
}
|
||||
|
||||
private boolean detectProxy() {
|
||||
try {
|
||||
ServerConfiguration.class.getDeclaredMethod("isProxyEnabled");
|
||||
return Bukkit.getServerConfig().isProxyEnabled();
|
||||
} catch (NoClassDefFoundError | NoSuchMethodException noSuchClassMethodEx) {
|
||||
// Ignore continue below
|
||||
}
|
||||
|
||||
try {
|
||||
if (isProxySupported("org.spigotmc.SpigotConfig", "bungee")) {
|
||||
return true;
|
||||
|
||||
@@ -28,6 +28,7 @@ package com.github.games647.fastlogin.bukkit;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.github.games647.fastlogin.bukkit.command.CrackedCommand;
|
||||
import com.github.games647.fastlogin.bukkit.command.PremiumCommand;
|
||||
import com.github.games647.fastlogin.bukkit.command.DeleteCommand;
|
||||
import com.github.games647.fastlogin.bukkit.listener.ConnectionListener;
|
||||
import com.github.games647.fastlogin.bukkit.listener.PaperCacheListener;
|
||||
import com.github.games647.fastlogin.bukkit.listener.protocollib.ProtocolLibListener;
|
||||
@@ -155,6 +156,7 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
|
||||
//register commands using a unique name
|
||||
Optional.ofNullable(getCommand("premium")).ifPresent(c -> c.setExecutor(new PremiumCommand(this)));
|
||||
Optional.ofNullable(getCommand("cracked")).ifPresent(c -> c.setExecutor(new CrackedCommand(this)));
|
||||
Optional.ofNullable(getCommand("fldelete")).ifPresent(c -> c.setExecutor(new DeleteCommand(this)));
|
||||
}
|
||||
|
||||
private boolean initializeFloodgate() {
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015-2024 games647 and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package com.github.games647.fastlogin.bukkit.command;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
|
||||
|
||||
public class DeleteCommand implements TabExecutor {
|
||||
private final FastLoginBukkit plugin;
|
||||
|
||||
public DeleteCommand(FastLoginBukkit plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the command to delete profiles.
|
||||
*/
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
|
||||
if (!sender.hasPermission(command.getPermission())) {
|
||||
plugin.getCore().sendLocaleMessage("no-permission", sender);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (plugin.getBungeeManager().isEnabled()) {
|
||||
sender.sendMessage("Error: Cannot delete profile entries when using BungeeCord!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (args.length < 1) {
|
||||
sender.sendMessage("Error: Must supply username to delete!");
|
||||
return false;
|
||||
}
|
||||
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
|
||||
int count = plugin.getCore().getStorage().deleteProfile(args[0]);
|
||||
if (!(sender instanceof ConsoleCommandSender)) {
|
||||
Bukkit.getScheduler().runTask(plugin, () -> {
|
||||
if (count == 0) {
|
||||
sender.sendMessage("Error: No profile entries found!");
|
||||
} else {
|
||||
sender.sendMessage("Deleted " + count + " matching profile entries");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
||||
List<String> list = new ArrayList<>();
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
if (p.getName().toLowerCase().startsWith(args[0])) {
|
||||
list.add(p.getName());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015-2024 games647 and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package com.github.games647.fastlogin.bukkit.hook;
|
||||
|
||||
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
|
||||
import com.github.games647.fastlogin.core.hooks.AuthPlugin;
|
||||
import com.rabbitcomapny.api.Identifier;
|
||||
import com.rabbitcomapny.api.LoginResult;
|
||||
import com.rabbitcomapny.api.PasskyAPI;
|
||||
import com.rabbitcomapny.api.RegisterResult;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class PasskyHook implements AuthPlugin<Player> {
|
||||
|
||||
private final FastLoginBukkit plugin;
|
||||
|
||||
public PasskyHook(FastLoginBukkit plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean forceLogin(Player player) {
|
||||
LoginResult result = PasskyAPI.forceLogin(new Identifier(player), true);
|
||||
if (!result.success) {
|
||||
plugin.getLog().error("Failed to force login {} via Passky: {}", player.getName(), result.status);
|
||||
}
|
||||
|
||||
return result.success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean forceRegister(Player player, String password) {
|
||||
RegisterResult result = PasskyAPI.forceRegister(new Identifier(player), password, true);
|
||||
if (!result.success) {
|
||||
plugin.getLog().error("Failed to register {} via Passky: {}", player.getName(), result.status);
|
||||
}
|
||||
|
||||
return result.success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRegistered(String playerName) {
|
||||
return PasskyAPI.isRegistered(new Identifier(playerName));
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,7 @@ import com.github.games647.fastlogin.bukkit.hook.LogItHook;
|
||||
import com.github.games647.fastlogin.bukkit.hook.LoginSecurityHook;
|
||||
import com.github.games647.fastlogin.bukkit.hook.UltraAuthHook;
|
||||
import com.github.games647.fastlogin.bukkit.hook.XAuthHook;
|
||||
import com.github.games647.fastlogin.bukkit.hook.PasskyHook;
|
||||
import com.github.games647.fastlogin.core.hooks.AuthPlugin;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -94,7 +95,7 @@ public class DelayedAuthHook implements Runnable {
|
||||
try {
|
||||
List<Class<? extends AuthPlugin<Player>>> hooks = Arrays.asList(AuthMeHook.class,
|
||||
CrazyLoginHook.class, LogItHook.class, LoginSecurityHook.class, UltraAuthHook.class,
|
||||
XAuthHook.class);
|
||||
XAuthHook.class, PasskyHook.class);
|
||||
|
||||
for (Class<? extends AuthPlugin<Player>> clazz : hooks) {
|
||||
String pluginName = clazz.getSimpleName();
|
||||
|
||||
@@ -30,6 +30,7 @@ softdepend:
|
||||
- LogIt
|
||||
- UltraAuth
|
||||
- xAuth
|
||||
- Passky
|
||||
|
||||
commands:
|
||||
${project.parent.name}:
|
||||
@@ -44,6 +45,11 @@ commands:
|
||||
usage: /<command> [player]
|
||||
permission: ${project.artifactId}.command.cracked
|
||||
|
||||
fldelete:
|
||||
description: 'Delete player profile data'
|
||||
usage: /<command> [player]
|
||||
permission: ${project.artifactId}.command.delete
|
||||
|
||||
permissions:
|
||||
${project.artifactId}.command.premium:
|
||||
description: 'Label themselves as premium'
|
||||
@@ -62,3 +68,7 @@ permissions:
|
||||
description: 'Label others as cracked'
|
||||
children:
|
||||
${project.artifactId}.command.cracked: true
|
||||
|
||||
${project.artifactId}.command.delete:
|
||||
description: 'Delete other players profile data'
|
||||
default: op
|
||||
@@ -140,7 +140,7 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-jdk14</artifactId>
|
||||
<version>2.0.13</version>
|
||||
<version>2.0.17</version>
|
||||
</dependency>
|
||||
|
||||
<!-- snakeyaml is present in Bungee, Spigot, so we could use this independent implementation -->
|
||||
@@ -154,7 +154,7 @@
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<version>2.2</version>
|
||||
<version>2.4</version>
|
||||
</dependency>
|
||||
|
||||
<!--Floodgate for Xbox Live Authentication-->
|
||||
@@ -203,7 +203,7 @@
|
||||
<dependency>
|
||||
<groupId>com.github.games647</groupId>
|
||||
<artifactId>craftapi</artifactId>
|
||||
<version>0.8.1</version>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Database driver included in Spigot -->
|
||||
|
||||
@@ -27,10 +27,9 @@ package com.github.games647.fastlogin.core;
|
||||
|
||||
import com.github.games647.craftapi.model.auth.Verification;
|
||||
import com.github.games647.craftapi.resolver.MojangResolver;
|
||||
import com.github.games647.craftapi.resolver.Options;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InetAddress;
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -44,38 +43,12 @@ import java.util.Optional;
|
||||
*/
|
||||
public class ProxyAgnosticMojangResolver extends MojangResolver {
|
||||
|
||||
private static final String HOST = "sessionserver.mojang.com";
|
||||
|
||||
/**
|
||||
* A formatting string containing a URL used to call the {@code hasJoined} method on mojang session servers.
|
||||
* <p>
|
||||
* Formatting parameters:
|
||||
* 1. The username of the player in question
|
||||
* 2. The serverId of this server
|
||||
*/
|
||||
public static final String ENDPOINT = "https://" + HOST + "/session/minecraft/hasJoined?username=%s&serverId=%s";
|
||||
|
||||
public ProxyAgnosticMojangResolver(Options options) {
|
||||
super(options);
|
||||
}
|
||||
@Override
|
||||
public Optional<Verification> hasJoined(String username, String serverHash, InetAddress hostIp)
|
||||
throws IOException {
|
||||
String url = String.format(ENDPOINT, username, serverHash);
|
||||
|
||||
HttpURLConnection conn = this.getConnection(url);
|
||||
int responseCode = conn.getResponseCode();
|
||||
|
||||
Verification verification = null;
|
||||
|
||||
// Mojang session servers send HTTP 204 (NO CONTENT) when the authentication seems invalid
|
||||
// If that's not our case, the authentication is valid, and so we can parse the response.
|
||||
if (responseCode != HttpURLConnection.HTTP_NO_CONTENT) {
|
||||
verification = this.parseRequest(conn, this::parseVerification);
|
||||
}
|
||||
|
||||
return Optional.ofNullable(verification);
|
||||
}
|
||||
|
||||
// Functional implementation of InputStreamAction, used in hasJoined method in parseRequest call
|
||||
protected Verification parseVerification(InputStream input) throws IOException {
|
||||
return this.readJson(input, Verification.class);
|
||||
return super.hasJoined(username, serverHash, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,9 +43,30 @@ public abstract class AbstractAsyncScheduler {
|
||||
this.processingPool = processingPool;
|
||||
}
|
||||
|
||||
public abstract CompletableFuture<Void> runAsync(Runnable task);
|
||||
public CompletableFuture<Void> runAsync(Runnable task) {
|
||||
return CompletableFuture.runAsync(() -> process(task), processingPool).exceptionally(error -> {
|
||||
logger.warn("Error occurred on thread pool", error);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
public abstract CompletableFuture<Void> runAsyncDelayed(Runnable task, Duration delay);
|
||||
public CompletableFuture<Void> runAsyncDelayed(Runnable task, Duration delay) {
|
||||
return CompletableFuture.runAsync(() -> {
|
||||
currentlyRunning.incrementAndGet();
|
||||
try {
|
||||
Thread.sleep(delay.toMillis());
|
||||
task.run();
|
||||
} catch (InterruptedException interruptedException) {
|
||||
// restore interrupt flag
|
||||
Thread.currentThread().interrupt();
|
||||
} finally {
|
||||
currentlyRunning.getAndDecrement();
|
||||
}
|
||||
}, processingPool).exceptionally(error -> {
|
||||
logger.warn("Error occurred on thread pool", error);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
protected void process(Runnable task) {
|
||||
currentlyRunning.incrementAndGet();
|
||||
|
||||
@@ -27,8 +27,6 @@ package com.github.games647.fastlogin.core.scheduler;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
@@ -46,30 +44,4 @@ public class AsyncScheduler extends AbstractAsyncScheduler {
|
||||
+ "Upgrade Java to 21+ for improved performance");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> runAsync(Runnable task) {
|
||||
return CompletableFuture.runAsync(() -> process(task), processingPool).exceptionally(error -> {
|
||||
logger.warn("Error occurred on thread pool", error);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> runAsyncDelayed(Runnable task, Duration delay) {
|
||||
return CompletableFuture.runAsync(() -> {
|
||||
currentlyRunning.incrementAndGet();
|
||||
try {
|
||||
Thread.sleep(delay.toMillis());
|
||||
process(task);
|
||||
} catch (InterruptedException interruptedException) {
|
||||
// restore interrupt flag
|
||||
Thread.currentThread().interrupt();
|
||||
} finally {
|
||||
currentlyRunning.getAndDecrement();
|
||||
}
|
||||
}, processingPool).exceptionally(error -> {
|
||||
logger.warn("Error occurred on thread pool", error);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
package com.github.games647.fastlogin.core.shared;
|
||||
|
||||
import com.github.games647.craftapi.resolver.MojangResolver;
|
||||
import com.github.games647.craftapi.resolver.Options;
|
||||
import com.github.games647.craftapi.resolver.http.RotatingProxySelector;
|
||||
import com.github.games647.fastlogin.core.CommonUtil;
|
||||
import com.github.games647.fastlogin.core.ProxyAgnosticMojangResolver;
|
||||
@@ -48,11 +49,9 @@ import net.md_5.bungee.config.YamlConfiguration;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
import java.net.Proxy.Type;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Duration;
|
||||
@@ -121,30 +120,35 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize the resolver based on the config parameter
|
||||
this.resolver = this.config.getBoolean("useProxyAgnosticResolver", false)
|
||||
? new ProxyAgnosticMojangResolver() : new MojangResolver();
|
||||
Options resolverOptions = new Options();
|
||||
resolverOptions.setMaxNameRequests(config.getInt("mojang-request-limit", 600));
|
||||
|
||||
antiBot = createAntiBotService(config.getSection("anti-bot"));
|
||||
Set<Proxy> proxies = config.getStringList("proxies")
|
||||
.stream()
|
||||
.map(proxy -> proxy.split(":"))
|
||||
.map(proxy -> new InetSocketAddress(proxy[0], Integer.parseInt(proxy[1])))
|
||||
.map(sa -> new Proxy(Type.HTTP, sa))
|
||||
.collect(toSet());
|
||||
|
||||
Collection<InetAddress> addresses = new HashSet<>();
|
||||
for (String localAddress : config.getStringList("ip-addresses")) {
|
||||
try {
|
||||
addresses.add(InetAddress.getByName(localAddress.replace('-', '.')));
|
||||
} catch (UnknownHostException ex) {
|
||||
plugin.getLog().error("IP-Address is unknown to us", ex);
|
||||
}
|
||||
if (!proxies.isEmpty()) {
|
||||
resolverOptions.setProxySelector(new RotatingProxySelector(proxies));
|
||||
}
|
||||
|
||||
resolver.setMaxNameRequests(config.getInt("mojang-request-limit"));
|
||||
resolver.setProxySelector(new RotatingProxySelector(proxies));
|
||||
resolver.setOutgoingAddresses(addresses);
|
||||
// TODO: Not available currently in craftapi?
|
||||
// Collection<InetAddress> addresses = new HashSet<>();
|
||||
// for (String localAddress : config.getStringList("ip-addresses")) {
|
||||
// try {
|
||||
// addresses.add(InetAddress.getByName(localAddress.replace('-', '.')));
|
||||
// } catch (UnknownHostException ex) {
|
||||
// plugin.getLog().error("IP-Address is unknown to us", ex);
|
||||
// }
|
||||
// }
|
||||
// resolver.setOutgoingAddresses(addresses);
|
||||
|
||||
// Initialize the resolver based on the config parameter
|
||||
this.resolver = this.config.getBoolean("useProxyAgnosticResolver", false)
|
||||
? new ProxyAgnosticMojangResolver(resolverOptions) : new MojangResolver(resolverOptions);
|
||||
|
||||
antiBot = createAntiBotService(config.getSection("anti-bot"));
|
||||
}
|
||||
|
||||
private AntiBotService createAntiBotService(Configuration botSection) {
|
||||
|
||||
@@ -32,6 +32,8 @@ public interface AuthStorage {
|
||||
|
||||
StoredProfile loadProfile(UUID uuid);
|
||||
|
||||
int deleteProfile(String name);
|
||||
|
||||
void save(StoredProfile playerProfile);
|
||||
|
||||
void close();
|
||||
|
||||
@@ -65,6 +65,8 @@ public abstract class SQLStorage implements AuthStorage {
|
||||
+ "` WHERE `Name`=? LIMIT 1";
|
||||
protected static final String LOAD_BY_UUID = "SELECT * FROM `" + PREMIUM_TABLE
|
||||
+ "` WHERE `UUID`=? LIMIT 1";
|
||||
protected static final String DELETE_BY_NAME = "DELETE FROM " + PREMIUM_TABLE
|
||||
+ " WHERE `Name` = ?";
|
||||
protected static final String INSERT_PROFILE = "INSERT INTO `" + PREMIUM_TABLE
|
||||
+ "` (`UUID`, `Name`, `Premium`, `Floodgate`, `LastIp`) " + "VALUES (?, ?, ?, ?, ?) ";
|
||||
// limit not necessary here, because it's unique
|
||||
@@ -143,6 +145,25 @@ public abstract class SQLStorage implements AuthStorage {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deleteProfile(String name) {
|
||||
try (Connection con = dataSource.getConnection();
|
||||
PreparedStatement deleteStmt = con.prepareStatement(DELETE_BY_NAME)) {
|
||||
deleteStmt.setString(1, name);
|
||||
|
||||
int rowsDeleted = deleteStmt.executeUpdate();
|
||||
if (rowsDeleted > 0) {
|
||||
log.info("Deleted {}'s profile data", name);
|
||||
} else {
|
||||
log.info("No profile data found for {}", name);
|
||||
}
|
||||
return rowsDeleted;
|
||||
} catch (SQLException sqlEx) {
|
||||
log.error("Failed to query profile: {}", name, sqlEx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<StoredProfile> parseResult(ResultSet resultSet) throws SQLException {
|
||||
if (resultSet.next()) {
|
||||
long userId = resultSet.getInt("UserID");
|
||||
|
||||
@@ -27,8 +27,6 @@ package com.github.games647.fastlogin.core.scheduler;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
@@ -46,33 +44,4 @@ public class AsyncScheduler extends AbstractAsyncScheduler {
|
||||
|
||||
logger.info("Using optimized green threads with Java 21");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> runAsync(Runnable task) {
|
||||
return CompletableFuture
|
||||
.runAsync(() -> process(task), processingPool)
|
||||
.exceptionally(error -> {
|
||||
logger.warn("Error occurred on thread pool", error);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> runAsyncDelayed(Runnable task, Duration delay) {
|
||||
return CompletableFuture.runAsync(() -> {
|
||||
currentlyRunning.incrementAndGet();
|
||||
try {
|
||||
Thread.sleep(delay);
|
||||
process(task);
|
||||
} catch (InterruptedException interruptedException) {
|
||||
// restore interrupt flag
|
||||
Thread.currentThread().interrupt();
|
||||
} finally {
|
||||
currentlyRunning.getAndDecrement();
|
||||
}
|
||||
}, processingPool).exceptionally(error -> {
|
||||
logger.warn("Error occurred on thread pool", error);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
12
pom.xml
12
pom.xml
@@ -83,7 +83,7 @@
|
||||
<plugin>
|
||||
<!-- Update compiler plugin for old Maven versions like GH runner -->
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.13.0</version>
|
||||
<version>3.14.0</version>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
@@ -106,7 +106,7 @@
|
||||
<plugin>
|
||||
<groupId>com.mycila</groupId>
|
||||
<artifactId>license-maven-plugin</artifactId>
|
||||
<version>4.5</version>
|
||||
<version>5.0.0</version>
|
||||
<configuration>
|
||||
<licenseSets>
|
||||
<licenseSet>
|
||||
@@ -134,7 +134,7 @@
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<version>3.4.0</version>
|
||||
<version>3.6.0</version>
|
||||
<configuration>
|
||||
<configLocation>checkstyle.xml</configLocation>
|
||||
<consoleOutput>true</consoleOutput>
|
||||
@@ -145,7 +145,7 @@
|
||||
<dependency>
|
||||
<groupId>com.puppycrawl.tools</groupId>
|
||||
<artifactId>checkstyle</artifactId>
|
||||
<version>10.17.0</version>
|
||||
<version>10.23.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
@@ -162,7 +162,7 @@
|
||||
<!-- Require newer versions for Junit5 support -->
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<version>3.5.3</version>
|
||||
<configuration>
|
||||
<!-- Work-around to make multi-release classes discoverable
|
||||
https://issues.apache.org/jira/browse/SUREFIRE-1731 -->
|
||||
@@ -221,7 +221,7 @@
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>5.10.3</version>
|
||||
<version>5.12.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -62,6 +62,20 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.13.0</version>
|
||||
<configuration>
|
||||
<annotationProcessors>
|
||||
<annotationProcessor>
|
||||
com.velocitypowered.api.plugin.ap.PluginAnnotationProcessor
|
||||
</annotationProcessor>
|
||||
</annotationProcessors>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.6.0</version>
|
||||
@@ -161,25 +175,15 @@
|
||||
<dependency>
|
||||
<groupId>com.velocitypowered</groupId>
|
||||
<artifactId>velocity-api</artifactId>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<version>3.4.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.moandjiezana.toml</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.spongepowered</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!--Velocity does not ship any database driver-->
|
||||
<dependency>
|
||||
<groupId>org.mariadb.jdbc</groupId>
|
||||
<artifactId>mariadb-java-client</artifactId>
|
||||
<version>3.4.0</version>
|
||||
<version>3.5.3</version>
|
||||
<exclusions>
|
||||
<!-- Exclude JNA implementation for WAFFLE - Windows Authentication Framework (mariadb)-->
|
||||
<exclusion>
|
||||
|
||||
@@ -46,7 +46,6 @@ import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
|
||||
import com.velocitypowered.api.event.proxy.ProxyShutdownEvent;
|
||||
import com.velocitypowered.api.plugin.Plugin;
|
||||
import com.velocitypowered.api.plugin.annotation.DataDirectory;
|
||||
import com.velocitypowered.api.proxy.InboundConnection;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
import com.velocitypowered.api.proxy.messages.ChannelMessageSink;
|
||||
@@ -58,6 +57,7 @@ import org.geysermc.geyser.GeyserImpl;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@@ -75,7 +75,7 @@ public class FastLoginVelocity implements PlatformPlugin<CommandSource> {
|
||||
private final ProxyServer server;
|
||||
private final Path dataDirectory;
|
||||
private final Logger logger;
|
||||
private final ConcurrentMap<InboundConnection, VelocityLoginSession> session = new MapMaker().weakKeys().makeMap();
|
||||
private final ConcurrentMap<InetSocketAddress, VelocityLoginSession> session = new MapMaker().weakKeys().makeMap();
|
||||
private static final String PROXY_ID_FILE = "proxyId.txt";
|
||||
|
||||
private FastLoginCore<Player, CommandSource, FastLoginVelocity> core;
|
||||
@@ -175,7 +175,7 @@ public class FastLoginVelocity implements PlatformPlugin<CommandSource> {
|
||||
return core;
|
||||
}
|
||||
|
||||
public ConcurrentMap<InboundConnection, VelocityLoginSession> getSession() {
|
||||
public ConcurrentMap<InetSocketAddress, VelocityLoginSession> getSession() {
|
||||
return session;
|
||||
}
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ public class ConnectListener {
|
||||
@Subscribe
|
||||
public void onGameProfileRequest(GameProfileRequestEvent event) {
|
||||
if (event.isOnlineMode()) {
|
||||
LoginSession session = plugin.getSession().get(event.getConnection());
|
||||
LoginSession session = plugin.getSession().get(event.getConnection().getRemoteAddress());
|
||||
if (session == null) {
|
||||
plugin.getLog().error("No active login session found for onlinemode player {}", event.getUsername());
|
||||
return;
|
||||
@@ -173,7 +173,7 @@ public class ConnectListener {
|
||||
}
|
||||
}
|
||||
|
||||
VelocityLoginSession session = plugin.getSession().get(player);
|
||||
VelocityLoginSession session = plugin.getSession().get(player.getRemoteAddress());
|
||||
if (session == null) {
|
||||
plugin.getLog().info("No active login session found on server connect for {}", player);
|
||||
return;
|
||||
@@ -193,7 +193,7 @@ public class ConnectListener {
|
||||
Player player = disconnectEvent.getPlayer();
|
||||
plugin.getCore().getPendingConfirms().remove(player.getUniqueId());
|
||||
|
||||
plugin.getSession().remove(player);
|
||||
plugin.getSession().remove(player.getRemoteAddress());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -127,7 +127,7 @@ public class PluginMessageListener {
|
||||
if (shouldPersist) {
|
||||
//bukkit module successfully received and force logged in the user
|
||||
//update only on success to prevent corrupt data
|
||||
VelocityLoginSession loginSession = plugin.getSession().get(forPlayer);
|
||||
VelocityLoginSession loginSession = plugin.getSession().get(forPlayer.getRemoteAddress());
|
||||
StoredProfile playerProfile = loginSession.getProfile();
|
||||
loginSession.setRegistered(true);
|
||||
if (!loginSession.isAlreadySaved()) {
|
||||
|
||||
@@ -58,7 +58,7 @@ public class AsyncPremiumCheck extends JoinManagement<Player, CommandSource, Vel
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
plugin.getSession().remove(connection);
|
||||
plugin.getSession().remove(connection.getRemoteAddress());
|
||||
super.onLogin(username, new VelocityLoginSource(connection, preLoginEvent));
|
||||
}
|
||||
|
||||
@@ -82,7 +82,8 @@ public class AsyncPremiumCheck extends JoinManagement<Player, CommandSource, Vel
|
||||
String username, boolean registered) {
|
||||
source.enableOnlinemode();
|
||||
VelocityLoginSession session = new VelocityLoginSession(username, registered, profile);
|
||||
plugin.getSession().put(source.getConnection(), session);
|
||||
plugin.getLog().error("Putting session: {}", source.getConnection());
|
||||
plugin.getSession().put(source.getConnection().getRemoteAddress(), session);
|
||||
|
||||
String ip = source.getAddress().getAddress().getHostAddress();
|
||||
plugin.getCore().addLoginAttempt(ip, username);
|
||||
@@ -91,6 +92,6 @@ public class AsyncPremiumCheck extends JoinManagement<Player, CommandSource, Vel
|
||||
@Override
|
||||
public void startCrackedSession(VelocityLoginSource source, StoredProfile profile, String username) {
|
||||
VelocityLoginSession session = new VelocityLoginSession(username, false, profile);
|
||||
plugin.getSession().put(source.getConnection(), session);
|
||||
plugin.getSession().put(source.getConnection().getRemoteAddress(), session);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ public class FloodgateAuthTask
|
||||
@Override
|
||||
protected void startLogin() {
|
||||
VelocityLoginSession session = new VelocityLoginSession(player.getUsername(), isRegistered, profile);
|
||||
core.getPlugin().getSession().put(player, session);
|
||||
core.getPlugin().getSession().put(player.getRemoteAddress(), session);
|
||||
|
||||
// enable auto login based on the value of 'autoLoginFloodgate' in config.yml
|
||||
boolean forcedOnlineMode = autoLoginFloodgate.equals("true")
|
||||
|
||||
Reference in New Issue
Block a user