8 changed files with 32 additions and 241 deletions
@ -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<String> 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<String> 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(); |
|||
}*/ |
|||
} |
|||
@ -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(); |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
@ -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(); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue