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