Skip to content

Commit

Permalink
1.0.9 release
Browse files Browse the repository at this point in the history
- registrations limit
- lowercase registrations fix
- ability to link account using a command like "!account link <username> <password>"
  • Loading branch information
hevav committed Jan 27, 2023
1 parent cffcb67 commit 6413891
Show file tree
Hide file tree
Showing 6 changed files with 195 additions and 25 deletions.
58 changes: 43 additions & 15 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,40 +1,68 @@
name: Java CI with Gradle

on: [ push, pull_request ]
on:
push:
branches:
- master
pull_request:
branches:
- master

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
java: [ 11, 17 ]
fail-fast: true
steps:
- name: Checkout
uses: actions/checkout@v2.4.0
- name: Set up JDK ${{ matrix.java }}
uses: actions/setup-java@v2.5.0
uses: actions/checkout@v3.0.0
- name: Set up JDK
uses: actions/setup-java@v3.0.0
with:
distribution: adopt
java-version: ${{ matrix.java }}
java-version: 11
- name: Build LimboAuth Social Addon
run: ./gradlew build
- name: Upload LimboAuth Social Addon
uses: actions/upload-artifact@v2.3.1
uses: actions/upload-artifact@v3.0.0
with:
name: LimboAuth Social Addon Built On ${{ matrix.java }} JDK
name: LimboAuth Social Addon
path: "build/libs/LimboAuth*.jar"
- uses: dev-drprasad/[email protected]
if: ${{ github.event_name == 'push' }}
with:
delete_release: true
tag_name: dev-build-jdk-${{ matrix.java }}
tag_name: dev-build
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Find git version
id: git-version
run: echo "id=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
- name: Find correct JAR
if: ${{ github.event_name == 'push' }}
id: find-jar
run: |
output="$(find build/libs/ ! -name "*-javadoc.jar" ! -name "*-sources.jar" -type f -printf "%f\n")"
echo "::set-output name=jarname::$output"
- name: Release the build
if: ${{ github.event_name == 'push' }}
uses: ncipollo/release-action@v1
with:
artifacts: "build/libs/LimboAuth*.jar"
artifacts: build/libs/${{ steps.find-jar.outputs.jarname }}
body: ${{ join(github.event.commits.*.message, '\n') }}
prerelease: true
name: JDK ${{ matrix.java }} Dev-build
tag: dev-build-jdk-${{ matrix.java }}
name: Dev-build ${{ steps.git-version.outputs.id }}
tag: dev-build
- name: Upload to Modrinth
if: ${{ github.event_name == 'push' }}
uses: RubixDev/[email protected]
with:
token: ${{ secrets.MODRINTH_TOKEN }}
file_path: build/libs/${{ steps.find-jar.outputs.jarname }}
name: Dev-build ${{ steps.git-version.outputs.id }}
version: ${{ steps.git-version.outputs.id }}
changelog: ${{ join(github.event.commits.*.message, '\n') }}
relations: 4iChqdl8:required
game_versions: 1.7.2
release_type: beta
loaders: velocity
featured: false
project_id: fPyQl4rd
52 changes: 52 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Java CI with Gradle

on:
release:
types: [published]

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/[email protected]
- name: Set up JDK
uses: actions/[email protected]
with:
distribution: adopt
java-version: 11
- name: Build LimboAuth Social Addon
run: ./gradlew build
- name: Upload LimboAuth Social Addon
uses: actions/[email protected]
with:
name: LimboAuth Social Addon
path: "build/libs/LimboAuth*.jar"
- name: Find correct JAR
id: find-jar
run: |
output="$(find build/libs/ ! -name "*-javadoc.jar" ! -name "*-sources.jar" -type f -printf "%f\n")"
echo "::set-output name=jarname::$output"
- name: Upload to the GitHub release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: build/libs/${{ steps.find-jar.outputs.jarname }}
asset_name: ${{ steps.find-jar.outputs.jarname }}
asset_content_type: application/java-archive
- name: Upload to Modrinth
uses: RubixDev/[email protected]
with:
token: ${{ secrets.MODRINTH_TOKEN }}
file_path: build/libs/${{ steps.find-jar.outputs.jarname }}
name: Release ${{ github.event.release.tag_name }}
version: ${{ github.event.release.tag_name }}
changelog: ${{ github.event.release.body }}
relations: 4iChqdl8:required
game_versions: 1.7.2
release_type: release
loaders: velocity
featured: false
project_id: fPyQl4rd
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.0.8
1.0.9
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ plugins {
}

setGroup("net.elytrium")
setVersion("1.0.8")
setVersion("1.0.9")

compileJava {
getOptions().setEncoding("UTF-8")
Expand Down
93 changes: 85 additions & 8 deletions src/main/java/net/elytrium/limboauth/socialaddon/Addon.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.ProxyServer;
import com.velocitypowered.api.proxy.ServerConnection;
import com.velocitypowered.api.scheduler.ScheduledTask;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.File;
import java.nio.file.Path;
Expand All @@ -43,12 +44,14 @@
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import net.elytrium.commons.config.Placeholders;
import net.elytrium.commons.kyori.serialization.Serializer;
import net.elytrium.commons.kyori.serialization.Serializers;
import net.elytrium.commons.utils.updates.UpdatesChecker;
import net.elytrium.limboauth.LimboAuth;
import net.elytrium.limboauth.handler.AuthSessionHandler;
import net.elytrium.limboauth.model.RegisteredPlayer;
import net.elytrium.limboauth.socialaddon.command.ForceSocialUnlinkCommand;
import net.elytrium.limboauth.socialaddon.command.ValidateLinkCommand;
Expand Down Expand Up @@ -103,13 +106,15 @@ public class Addon {

private final Map<String, Integer> codeMap;
private final Map<String, TempAccount> requestedReverseMap;
private final Map<String, CachedRegisteredUser> cachedAccountRegistrations = new ConcurrentHashMap<>();

private Dao<SocialPlayer, String> dao;
private Pattern nicknamePattern;

private SocialManager socialManager;
private List<List<AbstractSocial.ButtonItem>> keyboard;
private GeoIp geoIp;
private ScheduledTask purgeCacheTask;

static {
Objects.requireNonNull(org.apache.commons.logging.impl.LogFactoryImpl.class);
Expand Down Expand Up @@ -205,12 +210,25 @@ private void load() {
return;
}

String userIndex = dbField + id;
CachedRegisteredUser cachedRegisteredUser = this.cachedAccountRegistrations.get(userIndex);
if (cachedRegisteredUser == null) {
this.cachedAccountRegistrations.put(userIndex, cachedRegisteredUser = new CachedRegisteredUser());
}

if (cachedRegisteredUser.getRegistrationAmount() >= Settings.IMP.MAIN.MAX_REGISTRATION_COUNT_PER_TIME) {
this.socialManager.broadcastMessage(dbField, id, Settings.IMP.MAIN.STRINGS.REGISTER_LIMIT);
return;
}

cachedRegisteredUser.incrementRegistrationAmount();

if (this.dao.queryForEq(dbField, id).size() != 0) {
this.socialManager.broadcastMessage(dbField, id, Settings.IMP.MAIN.STRINGS.LINK_ALREADY);
return;
}

String account = message.substring(desiredLength).toLowerCase(Locale.ROOT);
String account = message.substring(desiredLength);
if (!this.nicknamePattern.matcher(account).matches()) {
this.socialManager.broadcastMessage(dbField, id, Settings.IMP.MAIN.STRINGS.REGISTER_INCORRECT_NICKNAME);
return;
Expand All @@ -230,11 +248,9 @@ private void load() {
String newPassword = Long.toHexString(Double.doubleToLongBits(Math.random()));

RegisteredPlayer player = new RegisteredPlayer(account, "", "").setPassword(newPassword);

this.plugin.getPlayerDao().create(player);

this.linkSocial(lowercaseNickname, dbField, id);

this.socialManager.broadcastMessage(dbField, id,
Placeholders.replace(Settings.IMP.MAIN.STRINGS.REGISTER_SUCCESS, newPassword));
}
Expand All @@ -249,21 +265,43 @@ private void load() {
return;
}

String[] args = message.substring(desiredLength).split(" ");
if (this.dao.queryForEq(dbField, id).size() != 0) {
this.socialManager.broadcastMessage(dbField, id, Settings.IMP.MAIN.STRINGS.LINK_ALREADY);
return;
}

String account = message.substring(desiredLength).toLowerCase(Locale.ROOT);
String account = args[0].toLowerCase(Locale.ROOT);
if (!this.nicknamePattern.matcher(account).matches()) {
this.socialManager.broadcastMessage(dbField, id, Settings.IMP.MAIN.STRINGS.LINK_UNKNOWN_ACCOUNT);
return;
}

int code = ThreadLocalRandom.current().nextInt(Settings.IMP.MAIN.CODE_LOWER_BOUND, Settings.IMP.MAIN.CODE_UPPER_BOUND);
this.codeMap.put(account, code);
this.requestedReverseMap.put(account, new TempAccount(dbField, id));
this.socialManager.broadcastMessage(dbField, id, Placeholders.replace(Settings.IMP.MAIN.STRINGS.LINK_CODE, String.valueOf(code)));
if (args.length == 1) {
if (Settings.IMP.MAIN.DISABLE_LINK_WITHOUT_PASSWORD) {
this.socialManager.broadcastMessage(dbField, id, Settings.IMP.MAIN.STRINGS.LINK_SOCIAL_CMD_USAGE);
return;
}

int code = ThreadLocalRandom.current().nextInt(Settings.IMP.MAIN.CODE_LOWER_BOUND, Settings.IMP.MAIN.CODE_UPPER_BOUND);
this.codeMap.put(account, code);
this.requestedReverseMap.put(account, new TempAccount(dbField, id));
this.socialManager.broadcastMessage(dbField, id, Placeholders.replace(Settings.IMP.MAIN.STRINGS.LINK_CODE, String.valueOf(code)));
} else {
if (Settings.IMP.MAIN.DISABLE_LINK_WITH_PASSWORD) {
this.socialManager.broadcastMessage(dbField, id, Settings.IMP.MAIN.STRINGS.LINK_SOCIAL_CMD_USAGE);
return;
}

RegisteredPlayer registeredPlayer = this.plugin.getPlayerDao().queryForId(account);
if (AuthSessionHandler.checkPassword(args[1], registeredPlayer, this.plugin.getPlayerDao())) {
this.linkSocial(account, dbField, id);
this.socialManager.broadcastMessage(dbField, id, Settings.IMP.MAIN.STRINGS.LINK_SUCCESS);
} else {
this.socialManager.broadcastMessage(dbField, id, Settings.IMP.MAIN.STRINGS.LINK_WRONG_PASSWORD);
return;
}
}

return;
}
Expand Down Expand Up @@ -533,6 +571,16 @@ public void onReload() throws SQLException {
));
this.server.getEventManager().register(this, new ReloadListener(this));

if (this.purgeCacheTask != null) {
this.purgeCacheTask.cancel();
}

this.purgeCacheTask = this.server.getScheduler()
.buildTask(this, () -> this.checkCache(this.cachedAccountRegistrations, Settings.IMP.MAIN.PURGE_REGISTRATION_CACHE_MILLIS))
.delay(net.elytrium.limboauth.Settings.IMP.MAIN.PURGE_CACHE_MILLIS, TimeUnit.MILLISECONDS)
.repeat(net.elytrium.limboauth.Settings.IMP.MAIN.PURGE_CACHE_MILLIS, TimeUnit.MILLISECONDS)
.schedule();

CommandManager commandManager = this.server.getCommandManager();
commandManager.unregister(Settings.IMP.MAIN.LINKAGE_MAIN_CMD);
commandManager.unregister(Settings.IMP.MAIN.FORCE_UNLINK_MAIN_CMD);
Expand All @@ -549,6 +597,13 @@ public void onReload() throws SQLException {
);
}

private void checkCache(Map<?, ? extends CachedUser> userMap, long time) {
userMap.entrySet().stream()
.filter(userEntry -> userEntry.getValue().getCheckTime() + time <= System.currentTimeMillis())
.map(Map.Entry::getKey)
.forEach(userMap::remove);
}

public void unregisterPlayer(String nickname) {
try {
SocialPlayer player = this.dao.queryForId(nickname.toLowerCase(Locale.ROOT));
Expand Down Expand Up @@ -624,6 +679,28 @@ public long getId() {

}

private static class CachedUser {

private final long checkTime = System.currentTimeMillis();

public long getCheckTime() {
return this.checkTime;
}
}

private static class CachedRegisteredUser extends CachedUser {

private int registrationAmount;

public int getRegistrationAmount() {
return this.registrationAmount;
}

public void incrementRegistrationAmount() {
this.registrationAmount++;
}
}

private static void setSerializer(Serializer serializer) {
SERIALIZER = serializer;
}
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/net/elytrium/limboauth/socialaddon/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ public static class MAIN {
@Comment("Disable unlinking?")
public boolean DISABLE_UNLINK = false;

@Comment("Disable commands like !account link <username>")
public boolean DISABLE_LINK_WITHOUT_PASSWORD = false;
@Comment("Disable commands like !account link <username> <password>")
public boolean DISABLE_LINK_WITH_PASSWORD = true;

@Comment("Default buttons state")
public boolean DEFAULT_BLOCKED = false;
public boolean DEFAULT_TOTP_ENABLED = false;
Expand Down Expand Up @@ -101,6 +106,12 @@ public static class MAIN {
})
public boolean AUTH_2FA_WITHOUT_PASSWORD = false;

@Comment("How long in milliseconds the player should wait before registering new account")
public long PURGE_REGISTRATION_CACHE_MILLIS = 86400000;

@Comment("How many accounts can register the player per time (per purge-registration-cache-millis)")
public int MAX_REGISTRATION_COUNT_PER_TIME = 3;

@Create
public MAIN.VK VK;

Expand Down Expand Up @@ -214,9 +225,11 @@ public static class STRINGS {
public String LINK_UNKNOWN_ACCOUNT = "There is no account with this nickname";
@Placeholders({"{CODE}"})
public String LINK_CODE = "🔑 Enter '/addsocial {CODE}' in game to complete account linking";
public String LINK_WRONG_PASSWORD = "Wrong password";
public String REGISTER_INCORRECT_NICKNAME = "There is no account with this nickname";
public String REGISTER_TAKEN_NICKNAME = "This nickname is already taken";
public String REGISTER_PREMIUM_NICKNAME = "This nickname belongs to a premium player";
public String REGISTER_LIMIT = "You've tried to registered numerous times!";
@Placeholders({"{PASSWORD}"})
public String REGISTER_SUCCESS = "✅ Account was successfully registered{NL}Your password: {PASSWORD}{NL}Use '!keyboard' to show keyboard";

Expand Down

0 comments on commit 6413891

Please sign in to comment.