Browse Source

ненавижу потоки 2

master
gsd 2 years ago
parent
commit
ea8672e7e8
  1. 17
      src/main/java/app/configs/ProtocolA2S.java
  2. 38
      src/main/java/app/entities/Stats.java
  3. 19
      src/main/java/app/entities/server/Server.java
  4. 2
      src/main/java/app/services/ServerService.java
  5. 2
      src/main/java/app/services/StatsService.java
  6. 2
      src/main/java/app/updates/PlayersUpdater.java

17
src/main/java/app/configs/ProtocolA2S.java

@ -14,28 +14,29 @@ import org.springframework.context.annotation.Scope;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
@Configuration //@Configuration
public class ProtocolA2S { public class ProtocolA2S {
//https://ribasco.github.io/async-gamequery-lib/examples/source_query_example.html#blocking-example //https://ribasco.github.io/async-gamequery-lib/examples/source_query_example.html#blocking-example
@Scope("prototype") //@Scope("prototype")
@Bean /*@Bean
public SourceQueryClient GetSourceQueryClient() { public SourceQueryClient GetSourceQueryClient() {
ExecutorService customExecutor = Executors.newFixedThreadPool(1); ExecutorService customExecutor = Executors.newCachedThreadPool();
SourceQueryOptions options = SourceQueryOptions.builder() SourceQueryOptions options = SourceQueryOptions.builder()
.option(FailsafeOptions.FAILSAFE_RATELIMIT_TYPE, RateLimitType.BURST) .option(FailsafeOptions.FAILSAFE_RATELIMIT_TYPE, RateLimitType.BURST)
.option(GeneralOptions.THREAD_EXECUTOR_SERVICE, customExecutor) .option(GeneralOptions.THREAD_EXECUTOR_SERVICE, customExecutor)
.build(); .build();
return new SourceQueryClient(options); return new SourceQueryClient(options);
} }
*/
@Scope("prototype") //@Scope("prototype")
/*
@Bean @Bean
public SourceRconClient GetSourceRconClient() { public SourceRconClient GetSourceRconClient() {
ExecutorService customExecutor = Executors.newFixedThreadPool(1); ExecutorService customExecutor = Executors.newCachedThreadPool();
SourceRconOptions options = SourceRconOptions.builder() SourceRconOptions options = SourceRconOptions.builder()
//.option(FailsafeOptions.FAILSAFE_RATELIMIT_TYPE, RateLimitType.BURST) //.option(FailsafeOptions.FAILSAFE_RATELIMIT_TYPE, RateLimitType.BURST)
.option(GeneralOptions.THREAD_EXECUTOR_SERVICE, customExecutor) .option(GeneralOptions.THREAD_EXECUTOR_SERVICE, customExecutor)
.build(); .build();
return new SourceRconClient(options); return new SourceRconClient(options);
} }*/
} }

38
src/main/java/app/entities/Stats.java

@ -8,8 +8,12 @@ import app.entities.server.players.RCONPlayer;
import com.fasterxml.jackson.annotation.JsonGetter; import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.ibasco.agql.core.enums.RateLimitType;
import com.ibasco.agql.core.exceptions.ReadTimeoutException; import com.ibasco.agql.core.exceptions.ReadTimeoutException;
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.SourceQueryClient;
import com.ibasco.agql.protocols.valve.source.query.SourceQueryOptions;
import com.ibasco.agql.protocols.valve.source.query.info.SourceQueryInfoResponse; import com.ibasco.agql.protocols.valve.source.query.info.SourceQueryInfoResponse;
import com.ibasco.agql.protocols.valve.source.query.players.SourceQueryPlayerResponse; import com.ibasco.agql.protocols.valve.source.query.players.SourceQueryPlayerResponse;
import com.ibasco.agql.protocols.valve.source.query.rcon.exceptions.RconException; import com.ibasco.agql.protocols.valve.source.query.rcon.exceptions.RconException;
@ -28,6 +32,8 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Data @Data
@Component @Component
@ -44,6 +50,7 @@ public class Stats {
HashMap<String, Long> uniq = new HashMap<>(); HashMap<String, Long> uniq = new HashMap<>();
HashMap<String, Long> updates = new HashMap<>(); HashMap<String, Long> updates = new HashMap<>();
Statistic statistic = new Statistic(); Statistic statistic = new Statistic();
@JsonGetter @JsonGetter
public Statistic getStatistic() { public Statistic getStatistic() {
statistic.setTotal_servers(servers.size()); statistic.setTotal_servers(servers.size());
@ -55,7 +62,7 @@ public class Stats {
statistic.setPlayer_max(0); statistic.setPlayer_max(0);
} }
if(statistic.getPlayer_max() < statistic.getPlayer_now()) { if (statistic.getPlayer_max() < statistic.getPlayer_now()) {
statistic.setPlayer_max(statistic.getPlayer_now()); statistic.setPlayer_max(statistic.getPlayer_now());
} }
return statistic; return statistic;
@ -67,20 +74,22 @@ public class Stats {
} }
public void UpdateUniq(String key, Long value) { public void UpdateUniq(String key, Long value) {
uniq.merge(key, value, (x,y) -> y); uniq.merge(key, value, (x, y) -> y);
} }
public void RefreshServerA2SData(ApplicationContext context, String server_name) throws IOException { public void RefreshServerA2SData(String server_name) throws IOException {
try (SourceQueryClient sourceQueryClient = context.getBean(SourceQueryClient.class)) { //try (SourceQueryClient sourceQueryClient = context.getBean(SourceQueryClient.class)) {
try (SourceQueryClient sourceQueryClient = GetSourceQueryClient()) {
sourceQueryClient.getInfo(getServers().get(server_name).getInetAddress()).whenComplete((info, error) -> { sourceQueryClient.getInfo(getServers().get(server_name).getInetAddress()).whenComplete((info, error) -> {
sourceQueryClient.getExecutor().shutdown(); if (!sourceQueryClient.getExecutor().isShutdown()) sourceQueryClient.getExecutor().shutdown();
if (error != null) { if (error != null) {
getServers().get(server_name).SetDownStatus(); getServers().get(server_name).SetDownStatus();
return; return;
} }
getServers().get(server_name).UpdateStatusFromA2S(info); getServers().get(server_name).UpdateStatusFromA2S(info);
}).join(); }).join();
} catch (CompletionException err) {} } catch (CompletionException err) {
}
if (!getServers().get(server_name).isStatus() || getServers().get(server_name).getPlayer_count() < 1) { if (!getServers().get(server_name).isStatus() || getServers().get(server_name).getPlayer_count() < 1) {
return; return;
@ -88,9 +97,10 @@ public class Stats {
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
//If player count > 0 make base player request //If player count > 0 make base player request
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
try (SourceQueryClient sourceQueryClient = context.getBean(SourceQueryClient.class)) { //try (SourceQueryClient sourceQueryClient = context.getBean(SourceQueryClient.class)) {
try (SourceQueryClient sourceQueryClient = GetSourceQueryClient()) {
sourceQueryClient.getPlayers(getServers().get(server_name).getInetAddress()).whenComplete((players, error) -> { sourceQueryClient.getPlayers(getServers().get(server_name).getInetAddress()).whenComplete((players, error) -> {
sourceQueryClient.getExecutor().shutdown(); if (!sourceQueryClient.getExecutor().isShutdown()) sourceQueryClient.getExecutor().shutdown();
if (error != null) return; if (error != null) return;
getServers().get(server_name).UpdatePlayersFromA2S(players); getServers().get(server_name).UpdatePlayersFromA2S(players);
}).join(); }).join();
@ -99,10 +109,20 @@ public class Stats {
//Extend current players of rcon result //Extend current players of rcon result
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
try { try {
String response = getServers().get(server_name).ExecuteRCON(context,"status"); String response = getServers().get(server_name).ExecuteRCON("status");
getServers().get(server_name).UpdatePlayersFromRCON(response); getServers().get(server_name).UpdatePlayersFromRCON(response);
} catch (RconException | CompletionException err) { } catch (RconException | CompletionException err) {
return; return;
} }
} }
@JsonIgnore
public SourceQueryClient GetSourceQueryClient() {
ExecutorService customExecutor = Executors.newCachedThreadPool();
SourceQueryOptions options = SourceQueryOptions.builder()
.option(FailsafeOptions.FAILSAFE_RATELIMIT_TYPE, RateLimitType.BURST)
.option(GeneralOptions.THREAD_EXECUTOR_SERVICE, customExecutor)
.build();
return new SourceQueryClient(options);
}
} }

19
src/main/java/app/entities/server/Server.java

@ -6,9 +6,11 @@ import app.entities.server.players.RCONPlayer;
import app.entities.server.players.SourcePlayer; import app.entities.server.players.SourcePlayer;
import com.fasterxml.jackson.annotation.*; import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.ibasco.agql.core.util.GeneralOptions;
import com.ibasco.agql.protocols.valve.source.query.info.SourceQueryInfoResponse; import com.ibasco.agql.protocols.valve.source.query.info.SourceQueryInfoResponse;
import com.ibasco.agql.protocols.valve.source.query.players.SourceQueryPlayerResponse; import com.ibasco.agql.protocols.valve.source.query.players.SourceQueryPlayerResponse;
import com.ibasco.agql.protocols.valve.source.query.rcon.SourceRconClient; 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 com.ibasco.agql.protocols.valve.source.query.rcon.message.SourceRconAuthResponse;
import com.ibasco.agql.protocols.valve.source.query.rcon.message.SourceRconCmdResponse; import com.ibasco.agql.protocols.valve.source.query.rcon.message.SourceRconCmdResponse;
import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaBuilder;
@ -21,6 +23,8 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Data @Data
public class Server { public class Server {
@ -108,11 +112,11 @@ public class Server {
} }
@JsonIgnore @JsonIgnore
public String ExecuteRCON(ApplicationContext context, String command) { public String ExecuteRCON(String command) {
try (SourceRconClient rconClient = context.getBean(SourceRconClient.class)) { try (SourceRconClient rconClient = GetSourceRconClient()) {
SourceRconAuthResponse response = rconClient.authenticate(getInetAddress(), getRcon_password().getBytes()).join(); SourceRconAuthResponse response = rconClient.authenticate(getInetAddress(), getRcon_password().getBytes()).join();
if (!response.isAuthenticated()) { if (!response.isAuthenticated()) {
rconClient.getExecutor().shutdown(); if (!rconClient.getExecutor().isShutdown()) rconClient.getExecutor().shutdown();
return null; return null;
} }
return rconClient.execute(getInetAddress(), command) return rconClient.execute(getInetAddress(), command)
@ -125,6 +129,15 @@ public class Server {
return ""; return "";
} }
} }
@JsonIgnore
public SourceRconClient GetSourceRconClient() {
ExecutorService customExecutor = Executors.newCachedThreadPool();
SourceRconOptions options = SourceRconOptions.builder()
//.option(FailsafeOptions.FAILSAFE_RATELIMIT_TYPE, RateLimitType.BURST)
.option(GeneralOptions.THREAD_EXECUTOR_SERVICE, customExecutor)
.build();
return new SourceRconClient(options);
}
public void SetDownStatus() { public void SetDownStatus() {
setStatus(false); setStatus(false);

2
src/main/java/app/services/ServerService.java

@ -22,6 +22,6 @@ public class ServerService {
public boolean kickPlayer(PlayerProfile playerProfile){ public boolean kickPlayer(PlayerProfile playerProfile){
if (playerProfile == null || playerProfile.getPlay_on() == null) return false; if (playerProfile == null || playerProfile.getPlay_on() == null) return false;
return stats.getServers().get(playerProfile.getPlay_on().getServer_id()) return stats.getServers().get(playerProfile.getPlay_on().getServer_id())
.ExecuteRCON(applicationContext, "sm_kick #%d kicked from backend".formatted(playerProfile.getPlay_on().getPlayer_id())).contains("kicked"); .ExecuteRCON("sm_kick #%d kicked from backend".formatted(playerProfile.getPlay_on().getPlayer_id())).contains("kicked");
} }
} }

2
src/main/java/app/services/StatsService.java

@ -51,6 +51,6 @@ public class StatsService {
public String rconExecute(String server_name, String command) { public String rconExecute(String server_name, String command) {
if (!stats.getServers().containsKey(server_name)) return "Invalid server name"; if (!stats.getServers().containsKey(server_name)) return "Invalid server name";
return stats.getServers().get(server_name).ExecuteRCON(applicationContext, command); return stats.getServers().get(server_name).ExecuteRCON(command);
} }
} }

2
src/main/java/app/updates/PlayersUpdater.java

@ -42,7 +42,7 @@ public class PlayersUpdater {
@Job(name = "Update A2S data on: %0", retries = 0) @Job(name = "Update A2S data on: %0", retries = 0)
public void UpdatePlayersOnServer(String server_name) throws IOException { public void UpdatePlayersOnServer(String server_name) throws IOException {
stats.RefreshServerA2SData(context, server_name); stats.RefreshServerA2SData(server_name);
stats.getUpdates().merge("servers", Instant.now().getEpochSecond(), (x, y) -> y); stats.getUpdates().merge("servers", Instant.now().getEpochSecond(), (x, y) -> y);
} }
} }

Loading…
Cancel
Save