diff --git a/pom.xml b/pom.xml
index 6a84ad8..c5bc050 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,7 +13,7 @@
18
18
UTF-8
- 3.5.7
+ 3.5.9
6.2.12
2.19.2
@@ -82,24 +82,19 @@
org.postgresql
postgresql
- 42.6.0
+ 42.7.8
+
+
+ org.apache.commons
+ commons-lang3
+ 3.20.0
+ compile
-
org.springframework.boot
spring-boot-starter-actuator
${spring.version}
-
- com.ibasco.agql
- agql-source-query
- 1.0.7
-
-
- com.ibasco.agql
- agql-source-rcon
- 1.0.7
-
com.maxmind.geoip2
geoip2
diff --git a/src/main/java/app/entities/a2s/internal/InternalValveClient.java b/src/main/java/app/entities/a2s/internal/InternalValveClient.java
deleted file mode 100644
index 55a41cf..0000000
--- a/src/main/java/app/entities/a2s/internal/InternalValveClient.java
+++ /dev/null
@@ -1,162 +0,0 @@
-package app.entities.a2s.internal;
-
-import app.entities.a2s.requests.RCONRequest;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.ibasco.agql.core.enums.RateLimitType;
-import com.ibasco.agql.core.util.FailsafeOptions;
-import com.ibasco.agql.core.util.GeneralOptions;
-import com.ibasco.agql.protocols.valve.source.query.SourceQueryClient;
-import com.ibasco.agql.protocols.valve.source.query.SourceQueryOptions;
-import com.ibasco.agql.protocols.valve.source.query.rcon.SourceRconClient;
-import com.ibasco.agql.protocols.valve.source.query.rcon.SourceRconOptions;
-import com.ibasco.agql.protocols.valve.source.query.rcon.message.SourceRconAuthResponse;
-
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-public abstract class InternalValveClient {
- @JsonIgnore
- private ExecutorService executorServices_query;
- @JsonIgnore
- private ExecutorService executorServices_rcon;
- @JsonIgnore
- private SourceRconClient sourceRconClient;
- @JsonIgnore
- private SourceQueryClient sourceQueryClient;
-
- @JsonIgnore
- public SourceRconClient GetSourceRconClient() {
- if (executorServices_rcon == null) executorServices_rcon = Executors.newCachedThreadPool();
- if (sourceRconClient == null) {
- SourceRconOptions options = SourceRconOptions.builder()
- .option(FailsafeOptions.FAILSAFE_RATELIMIT_TYPE, RateLimitType.SMOOTH)
- .option(GeneralOptions.THREAD_EXECUTOR_SERVICE, executorServices_rcon)
- .build();
- sourceRconClient = new SourceRconClient(options);
- }
- return sourceRconClient;
- }
-
-
- @JsonIgnore
- public SourceQueryClient GetSourceQueryClient() {
- if (executorServices_query == null) executorServices_query = Executors.newCachedThreadPool();
- if (sourceQueryClient == null) {
- SourceQueryOptions options = SourceQueryOptions.builder()
- .option(FailsafeOptions.FAILSAFE_RATELIMIT_TYPE, RateLimitType.SMOOTH)
- .option(GeneralOptions.THREAD_EXECUTOR_SERVICE, executorServices_query)
- .build();
- sourceQueryClient = new SourceQueryClient(options);
- }
- return sourceQueryClient;
- }
-
- @JsonIgnore
- public String ExecuteRCON(RCONRequest request) {
- try (SourceRconClient rconClient = GetSourceRconClient()) {
- SourceRconAuthResponse response = rconClient.authenticate(request.getInetAddress(), request.getPassword().getBytes()).join();
- if (!response.isAuthenticated()) {
- if (!rconClient.getExecutor().isShutdown()) rconClient.getExecutor().shutdown();
- return null;
- }
- return rconClient.execute(request.getInetAddress(), request.getCommand())
- .thenApplyAsync(out -> {
- rconClient.cleanup(true);
- return out.getResult();
- })
- .join();
- } catch (Exception err) {
- return "";
- }
- }
-
- /*
- * public void UpdateStatusFromA2S(SourceQueryInfoResponse response) {
- SetDownStatus();
- if (response == null) return;
-
- setMax_players(response.getResult().getMaxPlayers());
- setPlayer_count(response.getResult().getNumOfPlayers());
- setMap(response.getResult().getMapName());
- setStatus(true);
- }*/
- /*
- * public void RefreshServerA2SData(String server_name) {
- //try (SourceQueryClient sourceQueryClient = context.getBean(SourceQueryClient.class)) {
- try (SourceQueryClient sourceQueryClient = getServers().get(server_name).GetSourceQueryClient()) {
- sourceQueryClient.getInfo(getServers().get(server_name).getInetAddress()).whenComplete((info, error) -> {
- if (!sourceQueryClient.getExecutor().isShutdown()) sourceQueryClient.getExecutor().shutdown();
- if (error != null) {
- getServers().get(server_name).SetDownStatus();
- return;
- }
- getServers().get(server_name).UpdateStatusFromA2S(info);
- }).join();
- } catch (CompletionException | IOException err) {
- }
-
- if (!getServers().get(server_name).isStatus() || getServers().get(server_name).getPlayer_count() < 1) {
- return;
- }
- ////////////////////////////////////////////////////////////////////////
- //If player count > 0 make base player request
- ////////////////////////////////////////////////////////////////////////
- //try (SourceQueryClient sourceQueryClient = context.getBean(SourceQueryClient.class)) {
- try (SourceQueryClient sourceQueryClient = getServers().get(server_name).GetSourceQueryClient()) {
- sourceQueryClient.getPlayers(getServers().get(server_name).getInetAddress()).whenComplete((players, error) -> {
- if (!sourceQueryClient.getExecutor().isShutdown()) sourceQueryClient.getExecutor().shutdown();
- if (error != null) return;
- getServers().get(server_name).UpdatePlayersFromA2S(players);
- }).join();
- } catch (CompletionException | IOException err) {}
- ///////////////////////////////////////////////////////////////////////
- //Extend current players of rcon result
- //////////////////////////////////////////////////////////////////////
- try {
- String response = getServers().get(server_name).ExecuteRCON("status");
- getServers().get(server_name).UpdatePlayersFromRCON(response);
- } catch (RconException | CompletionException err) {
- return;
- }
- }*/
- /*
- * public void UpdatePlayersFromA2S(SourceQueryPlayerResponse response) {
- a2s_players.clear();
- if (response != null) {
- response.getResult().stream().map(app.entities.server.players.SourcePlayer::new).forEach(a2s_players::add);
- }
- }
-
- public void UpdatePlayersFromRCON(String response) {
- players.clear();
- int start_index = response.indexOf("# userid");
- if (start_index == -1) return;
- List players_list = Arrays.stream(response.substring(start_index, response.length()).split("\n")).toList();
- boolean skip_table_header = true;
- for(String player_text: players_list) {
- if (skip_table_header || player_text.length() < 1) {
- skip_table_header = false;
- continue;
- }
- /////////////////////////////////////////////////////
- List player_line = Arrays.stream(player_text.split("\\s+")).toList();
- RCONPlayer player;
- try {
- player = new RCONPlayer(player_line);
- } catch (Exception parse_err) {
- System.out.println("Cannot parse: " + player_line);
- continue;
- }
-
- for (SourcePlayer sourcePlayer: a2s_players) {
- if (sourcePlayer.getName().equals(player.getName())) {
- player.setScore(sourcePlayer.getScore());
- a2s_players.remove(sourcePlayer);
- players.add(player);
- break;
- }
- }
- }
- a2s_players.clear();
- }*/
-}
diff --git a/src/main/java/app/entities/db/DbFile.java b/src/main/java/app/entities/db/DbFile.java
index 62255dc..11ec1c3 100644
--- a/src/main/java/app/entities/db/DbFile.java
+++ b/src/main/java/app/entities/db/DbFile.java
@@ -1,9 +1,9 @@
package app.entities.db;
+import app.utils.FileUtils;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.*;
import lombok.Data;
-import org.apache.commons.compress.utils.FileNameUtils;
import java.sql.Timestamp;
import java.util.UUID;
@@ -43,6 +43,6 @@ public class DbFile {
private String tags;
public String getExtension() {
- return this.filename == null ? null : FileNameUtils.getExtension(this.filename);
+ return this.filename == null ? null : FileUtils.getFileExtension(this.filename);
}
}
diff --git a/src/main/java/app/entities/server/players/SourcePlayer.java b/src/main/java/app/entities/server/players/SourcePlayer.java
deleted file mode 100644
index 8de6123..0000000
--- a/src/main/java/app/entities/server/players/SourcePlayer.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package app.entities.server.players;
-
-import lombok.Data;
-
-@Data
-public class SourcePlayer extends DefaultPlayer {
- float duration;
-
- public SourcePlayer(com.ibasco.agql.protocols.valve.source.query.players.SourcePlayer player) {
- name = player.getName();
- duration = player.getDuration();
- score = player.getScore();
- }
-}
diff --git a/src/main/java/app/updates/CountriesUpdater.java b/src/main/java/app/updates/CountriesUpdater.java
index 966d81e..e1a4b54 100644
--- a/src/main/java/app/updates/CountriesUpdater.java
+++ b/src/main/java/app/updates/CountriesUpdater.java
@@ -57,9 +57,8 @@ public class CountriesUpdater extends BaseUpdater{
jdbcTemplate.query(countries_in_current_year, (rs, n) -> rs.getString("connect_ip")).forEach(ip -> {
try {
stats.getCountries().merge(geoIP.GetCountry(ip), 1, (x, y) -> x+y);
- } catch (UnknownHostException e) {
- } catch (IOException e) {
- } catch (GeoIp2Exception e) {
+ } catch (IOException | GeoIp2Exception e) {
+ logger.error("Cannot update country", e);
}
});
return true;
diff --git a/src/main/java/app/utils/FileUtils.java b/src/main/java/app/utils/FileUtils.java
new file mode 100644
index 0000000..323501b
--- /dev/null
+++ b/src/main/java/app/utils/FileUtils.java
@@ -0,0 +1,20 @@
+package app.utils;
+
+public class FileUtils {
+ public static String getFileExtension(String fileName) {
+ int lastDotIndex = fileName.lastIndexOf('.');
+
+ // Check for edge cases: no dot, or dot is the first character (e.g., ".gitignore")
+ if (lastDotIndex == -1 || lastDotIndex == 0) {
+ return ""; // No extension found or hidden file without extension
+ }
+
+ // Handle cases like "/path/to.a/file" where a directory has a dot
+ int lastSeparatorIndex = Math.max(fileName.lastIndexOf('/'), fileName.lastIndexOf('\\'));
+ if (lastDotIndex < lastSeparatorIndex) {
+ return ""; // The dot is part of the path, not the file name
+ }
+
+ return fileName.substring(lastDotIndex + 1);
+ }
+}
diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml
index aa3c32d..62b609b 100644
--- a/src/main/resources/application.yaml
+++ b/src/main/resources/application.yaml
@@ -73,7 +73,6 @@ backend:
logging:
level:
- com.ibasco.agql.core.util.*: OFF
app.entities.a2s.external.ExternalValveClient: WARN
app.utils.SaltedCookie: INFO
app.annotations.impl.WebAccessAspect: WARN
\ No newline at end of file
diff --git a/src/test/java/app/servers/TestServersA2S.java b/src/test/java/app/servers/TestServersA2S.java
deleted file mode 100644
index 0df182d..0000000
--- a/src/test/java/app/servers/TestServersA2S.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package app.servers;
-
-import app.entities.server.Server;
-import com.ibasco.agql.protocols.valve.source.query.SourceQueryClient;
-import org.junit.Test;
-
-import java.io.IOException;
-import java.util.concurrent.*;
-
-public class TestServersA2S {
- SourceQueryClient sourceQueryClient;
-
-
- public void check() throws InterruptedException {
- int count = 1;
- Server server = new Server();
- server.setAddress("192.168.3.3:27005");
-
- while (true) {
- try (SourceQueryClient sourceQueryClient = getClient()) {
- int finalCount = count;
- final CountDownLatch latch = new CountDownLatch(1);
- System.out.printf("[%d] Request\n", finalCount);
- sourceQueryClient.getInfo(null).whenComplete((info, error) -> {
- latch.countDown();
- if (error != null) {
- server.SetDownStatus();
- return;
- }
- System.out.printf("[%d] Player count: %d\n", finalCount, info.getResult().getNumOfPlayers());
- });
- latch.await();
- count++;
- } catch (CompletionException | IOException err) {
- err.printStackTrace();
- }
- Thread.sleep(500);
- }
- }
-
- public SourceQueryClient getClient() {
- //if (sourceQueryClient == null) sourceQueryClient = new SourceQueryClient();
- //return sourceQueryClient;
- return new SourceQueryClient();
- }
-}