Giter Site home page Giter Site logo

ribasco / async-gamequery-lib Goto Github PK

View Code? Open in Web Editor NEW
123.0 5.0 27.0 97.78 MB

A high-performance java game query library designed for steam/source based games and others

Home Page: https://ribasco.github.io/async-gamequery-lib/

License: Apache License 2.0

Java 99.83% Shell 0.11% Batchfile 0.05%
valve-cs netty source-engine source steam valve query library java java-8

async-gamequery-lib's Introduction

Asynchronous Game Query Library

Snapshot Builds Release Builds Site Builds Code Analysis

Maven Donate Javadocs Gitter

A game query library on steroids written for Java. It's an implementation of Valve's source Query, Rcon, Master and Steam Web API protocols. Built on top of Netty

Features

  • Simple and easy to use API.
  • All operations are asynchronous. Every request returns a CompletableFuture
  • It's fast and capable of handling large transactions.
  • Resource efficient
    • Uses netty's off-heap pooled direct buffers (Helps reduce GC pressure for high volume/throughput transactions)
    • Built-in thread and connection pooling support. Takes advantage of netty's event loop model.
    • Makes use of native transports (if available) for increased performance (e.g. epoll, kqueue). Java's NIO is used by default.
  • Highly Configurable. Clients can be configured to satisfy your requirements (e.g. providing a custom executor, adjusting rate limit parameters, selecting connection pool strategy etc.)
  • Throws meaningful exceptions. For example, in RCON, A MaxAttemptsReachedException will be thrown instead of a ReadTimeoutException (or a ChannelClosedException) to indicate that the maximum number of login attempts has been reached.
  • Transactions are Failsafe (except web api). Resilience policies have been implemented to guarantee the delivery and receipt of queries. Below are the policies available by default.
    • Retry Policy: A failed query is re-attempted until a response has either been received or the maximum number attempts has been reached.
    • Rate Limiter Policy: This prevents overloading the servers by sending requests too fast causing the requests to timeout due to rate limits being exceeded.
    • Circuit Breaker Policy: When certain number of failures reach the threshold, the library will transition to an "OPEN" state, temporarily rejecting new requests.

Usage

For more examples, please refer to the site docs.

Blocking Queries

public class BlockingQueryExample {

    //Use a custom executor. This is not really necessary as the library 
    //provides it's own default executor, this only serves an example.
    ExecutorService customExecutor = Executors.newCachedThreadPool();

    public static void main(String[] args) {
        // - Change rate limiting method to BURST
      // - Used a custom executor for query client. We are responsible for shutting down this executor, not the library.
      SourceQueryOptions queryOptions = SourceQueryOptions.builder()
                                                          .option(FailsafeOptions.FAILSAFE_RATELIMIT_TYPE, RateLimitType.BURST)
                                                          .option(GeneralOptions.THREAD_EXECUTOR_SERVICE, customExecutor)
                                                          .build();

        //You can instantiate the client from the try-with block as it implements the java.io.Closeable interface
        try (SourceQueryClient client = new SourceQueryClient(queryOptions)) {
            InetSocketAddress address = new InetSocketAddress("192.168.60.1", 27016);
            SourceServer info = client.getInfo(address).join().getResult();
            System.out.printf("INFO: %s\n", info);
        }
    }
}

Non-Blocking Queries

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;

public class NonBlockingQueryExample {

    //Use a custom executor. This is not required as the library 
    //provides it's own default global executor shared across all clients, this only serves an example on how you can provide your own.
    ExecutorService customExecutor = Executors.newCachedThreadPool();

    public static void main(String[] args) throws Exception {
      //Example configuration
      // - Enabled rate limiting, so we don't send too fast
      // - Change rate limiting type to SMOOTH (Two available types SMOOTH and BURST)
      // - Used a custom executor for query client. We are responsible for shutting down this executor, not the library.
      SourceQueryOptions queryOptions = SourceQueryOptions.builder()
                                                          .option(FailsafeOptions.FAILSAFE_RATELIMIT_TYPE, RateLimitType.SMOOTH)
                                                          .option(GeneralOptions.THREAD_EXECUTOR_SERVICE, customExecutor)
                                                          .build();

        //create a countdown latch with value of 1 since we are only expecting to receive 1 result
        CountDownLatch latch = new CountDownLatch(1);

        //Instantiate the client (constructor argument is optional)
        try (SourceQueryClient client = new SourceQueryClient(queryOptions)) {
            //Create a user defined object which serves as an aggregate where all the resulting data will be stored
            SourceQueryAggregate result = new SourceQueryAggregate(address);
            CompletableFuture<SourceQueryInfoResponse> infoFuture = client.getInfo(address);

            //Check if the future is complete
            if (infoFuture.isDone()) {
                try {
                    SourceQueryInfoResponse response = infoFuture.getNow(null);
                } catch (Exception e) {
                    e.printStackTrace(System.err);
                } finally {
                    latch.countDown();
                }
            }
            //If not, register a callback to handle future response
            else {
                infoFuture.whenComplete(new BiConsumer<SourceQueryInfoResponse, Throwable>() {
                    @Override
                    public void accept(SourceQueryInfoResponse response, Throwable error) {
                        try {
                            if (error != null) {
                                throw new CompletionException(error);
                            }
                            assert response != null;
                            System.out.printf("INFO: %s\n", response.getResult());
                        } finally {
                            latch.countDown();
                        }
                    }
                });
            }

          //REMEMBER: Since we are executing an asynchronous operation, 
          // we need to wait until we have received a response from the server, 
          // otherwise the program might abruptly terminate. 
          latch.await();
        }
    }
}

A slightly advanced example demonstrating how to combine all three asynchronous queries into one call. For more advanced examples (e.g. sending requests by batch, using synchronization barriers etc), please check out the examples module in the project source.

public class NonBlockingQueryExample {

    //Use a custom executor. This is not required as the library 
    //provides it's own default global executor shared across all clients, this only serves an example on how you can provide your own.
    ExecutorService customExecutor = Executors.newCachedThreadPool();

    public static void main(String[] args) {
        //Example configuration
        // - Enabled rate limiting so we don't send too fast
        // - Change rate limiting type to SMOOTH (Two available types SMOOTH and BURST)
      // - Used a custom executor for query client. We are responsible for shutting down this executor, not the library.
      SourceQueryOptions queryOptions = SourceQueryOptions.builder()
                                                          .option(SourceQueryOptions.FAILSAFE_RATELIMIT_TYPE, RateLimitType.SMOOTH)
                                                          .option(GeneralOptions.THREAD_EXECUTOR_SERVICE, customExecutor)
                                                          .build();
        //Instantiate the client (constructor argument is optional)
        SourceQueryClient client = new SourceQueryClient(queryOptions);

        //Create a user defined object which serves as an aggregate where all the resulting data will be stored
        SourceQueryAggregate result = new SourceQueryAggregate(address);

        //Combining all queries in one call
        //Note: `Functions::selectFirst` is simply a utility function which returns the first argument of the callback (Refer to the examples section for the source) 
        CompletableFuture<SourceQueryAggregate> resultFuture = CompletableFuture.completedFuture(result)
                                                                                .thenCombine(client.getInfo(address).handle(result.ofType(SourceQueryType.INFO)), Functions::selectFirst)
                                                                                .thenCombine(client.getPlayers(address).handle(result.ofType(SourceQueryType.PLAYERS)), Functions::selectFirst)
                                                                                .thenCombine(client.getRules(address).handle(result.ofType(SourceQueryType.RULES)), Functions::selectFirst);

        //Display result
        resultFuture.whenComplete(new BiConsumer<SourceQueryAggregate, Throwable>() {
            @Override
            public void accept(SourceQueryAggregate result, Throwable error) {
                if (error != null) {
                    throw new CompletionException(error);
                }
                log.info("INFO: {}, PLAYERS: {}, RULES: {}", result.getInfo(), result.getPlayers(), result.getRules());
            }
        });
    }
}

Failsafe Demo

A couple of demonstration videos showcasing the built-in failsafe features provided by this library.

Retry Feature

  • A batch of 5000 requests were sent to a single instance and changelevel was issued, triggering active connections to get dropped by the remote server. The failed requests were retried and recovers successfully. All futures transitioned to a completed state.
rcon_failsafe_retry.mp4

Circuit Breaker (Fail-fast)

  • A batch of 5000 requests were sent to a single instance. In the middle of the operation, the server was restarted triggering all remaining futures to timeout, resulting with the internal circuit breaker to transition in OPEN state.
rcon_failsafe_circuit_breaker.mp4

Project Resources

Discussion Platforms

If you have any inquiries,concerns or suggestions please use one of the official communication channels for this project

Implementations

Below is the list of what is currently implemented on the library

  • Valve Master Server Query Protocol
  • Valve Source Query Protocol
  • Valve Steam Web API
  • Valve Steam StoreFront Web API
  • Valve Dota 2 Web API
  • Valve CS:GO Web API
  • Valve Source Log Service (A service which allows you to recive server log events)
  • Supercell Clash of Clans Web API (Deprecated)

Requirements

  • Java JDK 8 or above

Installation

Just add the following dependencies to your maven pom.xml. Only include the modules you need.

Install from Maven Central

Aggregate (All modules included in this artifact)

<dependency>
    <groupId>com.ibasco.agql</groupId>
  <artifactId>agql</artifactId>
  <version>1.2.2</version>
</dependency>

Valve Master Server Query Protocol

<dependency>
    <groupId>com.ibasco.agql</groupId>
  <artifactId>agql-steam-master</artifactId>
  <version>1.2.2</version>
</dependency>

Valve Source Query Protocol

<dependency>
  <groupId>com.ibasco.agql</groupId>
  <artifactId>agql-source-query</artifactId>
  <version>1.2.2</version>
</dependency>

Valve Source Log Listener Service

<dependency>
  <groupId>com.ibasco.agql</groupId>
  <artifactId>agql-source-log</artifactId>
  <version>1.2.2</version>
</dependency>

Valve Source Rcon Protocol

<dependency>
  <groupId>com.ibasco.agql</groupId>
  <artifactId>agql-source-rcon</artifactId>
  <version>1.2.2</version>
</dependency>

Valve Steam Web API

<dependency>
  <groupId>com.ibasco.agql</groupId>
  <artifactId>agql-steam-webapi</artifactId>
  <version>1.2.2</version>
</dependency>

Valve Dota 2 Web API

<dependency>
    <groupId>com.ibasco.agql</groupId>
  <artifactId>agql-dota2-webapi</artifactId>
  <version>1.2.2</version>
</dependency>

Valve CS:GO Web API

<dependency>
    <groupId>com.ibasco.agql</groupId>
  <artifactId>agql-csgo-webapi</artifactId>
  <version>1.2.2</version>
</dependency>

Supercell Clash of Clans Web API (Deprecated)

NOTE: As of 1.0.0, this has been marked as deprecated and will be removed in the next major release

<dependency>
    <groupId>com.ibasco.agql</groupId>
  <artifactId>agql-coc-webapi</artifactId>
  <version>1.2.2</version>
</dependency>

Install from Source

Clone from remote repository then mvn install. All the modules will be installed to your local maven repository.

git clone https://github.com/ribasco/async-gamequery-lib.git
cd async-gamequery-lib
mvn install

Interactive Examples

RCON interactive example video

To run the available examples, I have included a convenience script (run-example.sh or run-example.cmd) that will allow you to pick a specific example you could run.

The script accepts a "key" that represents an example application. To get a list of keys, simply invoke the script without arguments, for example:

$ ./run-example.sh
Error: Missing Example Key. Please specify the example key. (e.g. source-query)

====================================================================
List of available examples
====================================================================
- Source Server Query Example      (key: source-query)
- Master Server Query Example      (key: master-query)
- Source Rcon Example              (key: source-rcon)
- Clash of Clans Web API Example   (key: coc-webapi)
- CS:GO Web API Example            (key: csgo-webapi)
- Steam Web API Example            (key: steam-webapi)
- Steam Storefront Web API Example (key: steam-store-webapi)
- Source Log Listener Example      (key: source-logger)
- Steam Econ Web API Example       (key: steam-econ-webapi)
- Dota2 Web API Example            (key: dota2-webapi)

If you are running a web service type example, you will be prompted with an API key. Simply copy and paste the key to the console.

$ ./run-example.sh coc-webapi
Running example for coc-webapi
$ Please input your API Token:

Note:

  • Don't forget to perform a mvn clean install before running an example

Protocol Specifications

References you might find helpful regarding the implementations

Demo Application

Coming soon (Currently working on a desktop application showcasing the features provided by this library). For now, refer to the interactive examples.

Contributing

Fork it and submit a pull request. Any type of contributions are welcome.

Special Thanks

  • ej Technologies - Developer of the award-winning JProfiler, a full-featured "All-in-one" Java Profiler. Click on the icon below to find out more.

    JProfiler

  • JetBrains - For providing the open-source license for their awesome Java IDE.

    IntelliJ IDEA

async-gamequery-lib's People

Contributors

darkatra avatar dependabot[bot] avatar john-chan avatar mikeporterdev avatar quanticc avatar ribasco avatar wwisser avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

async-gamequery-lib's Issues

Implement /clans/{clanTag}/currentwar

Description:
Retrieve information about clan's current clan war

Reference issue: #15

Implementation Details:

Interface: CocClans

Method: getCurrentWarInfo()

Return Type: CocClanCurrentWar

JSON Schema:

{
  "state": "string",
  "teamSize": 0,
  "preparationStartTime": "string",
  "startTime": "string",
  "endTime": "string",
  "clan": {
    "tag": "string",
    "name": "string",
    "badgeUrls": {
      "small": "string",
      "large": "string",
      "medium": "string"
    },
    "clanLevel": 0,
    "attacks": 0,
    "stars": 0,
    "expEarned": 0
  },
  "opponent": {
    "tag": "string",
    "name": "string",
    "badgeUrls": {
      "small": "string",
      "large": "string",
      "medium": "string"
    },
    "clanLevel": 0,
    "attacks": 0,
    "stars": 0,
    "expEarned": 0
  }
}

Parameters:

Parameter Value Description Parameter Type Data Type
clanTag required Tag of the clan whose war log to retrieve. path string

Remove caching mechanisms in Rcon and Query modules

Currently, the library provides built-in mechanisms for caching the credentials and challenge server requests. I now realized this is bad practice and insecure. This should be done by the developer instead.

To avoid data loss,if library cant determine int types exactly, let caller side handle it

Thanks for fix #13,but match_id is not the only one need fix,i am sure match_seq_num(IDOTA2Match_570/GetMatchHistory) is int64 type too.
In my understanding,there is no offical doc for those data2 api,right? so we have to guess what is the right one,and test/verify them manually,i think it so hard for you to test them all,and they may changed in the future.

In my opinion,the library dont have to map data types (in fact,int types) strictly,let caller handle it,this is can be done by the follow workaround:

  • avoid different data type between pojos/resquest-interfaces(e.g. account_id is long type in Dota2GamePlayer ,but int type in Dota2FantasyProPlayerInfo and Dota2Fantasy.getPlayerOfficialInfo)
  • if we cant makesure the right data type,use a 'larger' type,e.g. use long foraccount_id,last_update_time,time_joined instead of int,let caller chose what should send to server,if server side accept it ,it works,if not,caller should make change,not the library.
  • if library have to do type conversion in some case,especially a narrowing primitive conversion ,libaray should check (or report) for data loss,who convert who check ,right?

what you think of this idea?

Thank again for share this awesome project,cheers .

Resource was not found

Errors encountered during test:

Exception in thread "main" java.util.concurrent.ExecutionException: com.ibasco.agql.core.exceptions.ResourceNotFoundException: Resource was not found.
	at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357)
	at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895)
	at com.ibasco.agql.examples.Dota2WebApiQueryEx.run(Dota2WebApiQueryEx.java:70)
	at com.ibasco.agql.examples.Dota2WebApiQueryEx.main(Dota2WebApiQueryEx.java:48)
Caused by: com.ibasco.agql.core.exceptions.ResourceNotFoundException: Resource was not found.
	at com.ibasco.agql.core.AbstractWebApiInterface.interceptResponse(AbstractWebApiInterface.java:172)
	at java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:760)
	at java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:736)
	at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:474)
	at java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:1962)
	at org.asynchttpclient.netty.NettyResponseFuture.loadContent(NettyResponseFuture.java:223)
	at org.asynchttpclient.netty.NettyResponseFuture.done(NettyResponseFuture.java:258)
	...

Affected interfaces:

  • Dota2Econ.getItemIconPath()
  • Dota2Fantasy.getProPlayerList()
  • Dota2Match.getLeagueListing()
  • Dota2Teams.getTeamInfo()

Seems like they are no longer available for *_570 interfaces.

Reference: steam webapi documentation (xpaw)

Should be removed from the next major release

Time out while retrieving Player list.

Describe the bug
When trying to retrieve Player list from a Garry's Mod server through the example in the documentation, program returns a timed out.

Expected behavior
It should have returned me a list of SourcePlayer.

Thanks for your help.

[Dota 2 Web API] bug report for Dota2Heroes,match_seq_num

AGQL version

0.1.5

bugs

1. pojo object Dota2Heroes should have a filed for localized_name .

The original response(from https://api.steampowered.com/IEconDOTA2_570/GetHeroes/v1?language=en&itemizedonly=false&key=) :

{
"result": {
	"heroes": [
		{
		"name": "npc_dota_hero_antimage",
		"id": 1,
		"localized_name": "Anti-Mage"
		},
		{
		"name": "npc_dota_hero_axe",
		"id": 2,
		"localized_name": "Axe"
		}
		...
		]
	}
}

Maybe the class Dota2Heroes should rename to Dota2Hero

2. match_seq_num is not int32

For example,check the original response(from https://api.steampowered.com/IDOTA2Match_570/GetMatchHistory/v1?account_id=125038361&key=) :

{
"result": {
	"status": 1,
	"num_results": 100,
	"total_results": 199,
	"results_remaining": 99,
	"matches": [
		{
		"match_id": 3530014921,
		"match_seq_num": 3071690874,
		"start_time": 1509289271,
		"lobby_type": 0,
		"radiant_team_id": 0,
		"dire_team_id": 0,
		"players": [ ... ]
		},
		...
		]
	}

}

Maybe it a unsigned int32 or int64 type on server side, as a java client we should use long to avoid data losss .

related pojo object:Dota2MatchDetails,Dota2MatchHistory,Dota2MatchHistoryInfo

[LOL WebAPI] League of Legends Web API Implementation

Implement League of Legends Web API

Champion

  • Retrieve all champions
  • Retrieve champion by ID

ChampionMastery

  • Get a champion mastery by player id and champion id
  • Get all champion mastery entries sorted by number of champion points descending
  • Get a player's total champion mastery score, which is sum of individual champion mastery levels
  • Get specified number of top champion mastery entries sorted by number of champion points descending

CurrentGame

  • Get current game information for the given summoner ID

FeaturedGames

  • Get list of featured games

Game

  • Get recent games by summoner ID

League

  • Get leagues mapped by summoner ID for a given list of summoner IDs
  • Get league entries mapped by summoner ID for a given list of summoner IDs
  • Get challenger tier leagues
  • Get master tier leagues

StaticData

  • Retrieves champion list.
  • Retrieves a champion by its id.
  • Retrieves item list.
  • Retrieves item by its unique id.
  • Retrieve language strings data.
  • Retrieve supported languages data.
  • Retrieve map data.
  • Retrieves mastery list.
  • Retrieves mastery item by its unique id.
  • Retrieve realm data.
  • Retrieves rune list.
  • Retrieves rune by its unique id.
  • Retrieves summoner spell list.
  • Retrieves summoner spell by its unique id.
  • Retrieve version data.

Status

  • Get shard status
  • Get shard list

Match

  • Retrieve match by match ID

MatchList

  • Retrieve match list by summoner ID

Stats

  • Get ranked stats by summoner ID
  • Get player stats summaries by summoner ID

Summoner

Region: BR, EUNE, EUW, JP, KR, LAN, LAS, NA, OCE, RU, TR

  • Get a List of summoners by summoner names
  • Get a List of summoners by summoner ids
  • Get summoner names mapped by summoner ID for a given list of summoner IDs

Region: EUW, JP, NA, OCE, RU, TR

  • Get mastery pages mapped by summoner ID for a given list of summoner IDs
  • Get rune pages mapped by summoner ID for a given list of summoner IDs

Region: BR, EUNE, EUW, JP, KR, LAN, LAS, OCE, RU

  • Get summoner objects mapped by standardized summoner name for a given list of summoner names
  • Get summoner objects mapped by summoner ID for a given list of summoner IDs
  • Get mastery pages mapped by summoner ID for a given list of summoner IDs
  • Get summoner names mapped by summoner ID for a given list of summoner IDs
  • Get rune pages mapped by summoner ID for a given list of summoner IDs.

[COC WebApi] Implement /locations/{locationId}/rankings/players-versus

Description:
Get player versus rankings for a specific location

Implementation Details:

Interface: CocLocations

Method: getPlayerVsRankingsForLoc()

Return Type: CocLocationPlayerVsRanks

JSON Schema:

{
  "items": [
    {
      "tag": "string",
      "name": "string",
      "expLevel": 0,
      "rank": 0,
      "previousRank": 0,
      "versusTrophies": 0,
      "clan": {
        "tag": "string",
        "name": "string",
        "badgeUrls": {
          "small": "string",
          "large": "string",
          "medium": "string"
        }
      },
      "versusBattleWins": 0
    }
  ]
}

Parameters:

Parameter Value Description Parameter Type Data Type
location id Identifier of the location to retrieve. path string
limit Limit the number of items returned in the response. query integer
after Return only items that occur after this marker. After marker can be found from the response, inside the 'paging' property. Note that only after or before can be specified for a request, not both. query integer
before Return only items that occur before this marker. Before marker can be found from the response, inside the 'paging' property. Note that only after or before can be specified for a request, not both. query integer

[Storefront WebAPI] com.google.gson.JsonSyntaxException thrown from getAppDetails in Stean Store Front Interface

Discovered while testing SteamStorefront.getAppDetails() on random apps.

App Id: 410

java.util.concurrent.CompletionException: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at path $.linux_requirements
	at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:273)
	at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:280)
	at java.util.concurrent.CompletableFuture.uniApply(CompletableFuture.java:604)
	at java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:577)
	at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:474)

EDIT:
Some of the properties in the response return either as an array or as an object causing the parser to fail as it is only expecting one type. Example below:

Test Case 1: http://store.steampowered.com/api/appdetails/?appids=410

"linux_requirements": []

Test Case 2: http://store.steampowered.com/api/appdetails/?appids=550

"linux_requirements": {
"minimum": "<strong>Minimum:</strong><br><ul class=\"bb_ul\"><li><strong>OS:</strong> Ubuntu 12.04<br></li><li><strong>Processor:</strong> Dual core from Intel or AMD at 2.8 GHz<br></li><li><strong>Memory:</strong> 2 GB RAM<br></li><li><strong>Graphics:</strong> nVidia GeForce 8600/9600GT, ATI/AMD Radeon HD2600/3600 (Graphic Drivers: nVidia 310, AMD 12.11), OpenGL 2.1<br></li><li><strong>Storage:</strong> 13 GB available space<br></li><li><strong>Sound Card:</strong> OpenAL Compatible Sound Card</li></ul>"
}

GetMatchHistoryBySequenceNum not work

because startSeqNum is used to pass match sequence number which is a 64 bit integer,but the constructor of GetMatchHistoryBySequenceNum only accept int32.

[Steam Storefront API] java.lang.ClassCastException: java.lang.String cannot be cast to com.google.gson.JsonElement on any Steam Storefront calls

Tested with the following

SteamStorefront steamStorefront = new SteamStorefront(client);
CompletableFuture<StoreFeaturedApps> featuredApps = steamStorefront.getFeaturedApps();
StoreFeaturedApps storeFeaturedApps = featuredApps.get();

Causes

Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to com.google.gson.JsonElement
	at com.ibasco.agql.core.AbstractWebApiInterface.postProcessConversion(AbstractWebApiInterface.java:191)
	at java.util.concurrent.CompletableFuture.uniApply(CompletableFuture.java:602)
	at java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:577)
	at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:474)
	at java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:1962)
	at org.asynchttpclient.netty.NettyResponseFuture.getContent(NettyResponseFuture.java:219)
	at org.asynchttpclient.netty.NettyResponseFuture.done(NettyResponseFuture.java:254)
	at org.asynchttpclient.netty.handler.AsyncHttpClientHandler.finishUpdate(AsyncHttpClientHandler.java:241)
	at org.asynchttpclient.netty.handler.HttpHandler.handleChunk(HttpHandler.java:120)

Drilling down into it with a debugger it looks like this might be due to the 302 Moved Temporarily of the Http call to the Steam store being moved to Https. I think changing http to https in SteamApiConstants.java line 90 should fix this

java.net.SocketException: No buffer space available

Need to investigate. Seems like UDP ports aren't released properly.

2022-06-17 20:16:46,975 DEBUG com.ibasco.agql.core.transport.FailsafeChannelFactory$ChannelSupplier [sb-agql-2-6] CHANNEL_FACTORY (FailsafeChannelFactory) => Acquiring channel for address '/155.133.252.121:27162' (Supplier: com.ibasco.agql.core.transport.FailsafeChannelFactory$ChannelSupplier@31c88936, Attempt: 1, Executions: 1, Last Result: null, Last Failure: {})
java.net.SocketException: No buffer space available (maximum connections reached?): bind
	at java.base/sun.nio.ch.Net.bind0(Native Method)
	at java.base/sun.nio.ch.Net.bind(Net.java:555)
	at java.base/sun.nio.ch.DatagramChannelImpl.bindInternal(DatagramChannelImpl.java:1194)
	at java.base/sun.nio.ch.DatagramChannelImpl.bind(DatagramChannelImpl.java:1164)
	at io.netty.util.internal.SocketUtils$6.run(SocketUtils.java:133)
	at io.netty.util.internal.SocketUtils$6.run(SocketUtils.java:130)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
	at io.netty.util.internal.SocketUtils.bind(SocketUtils.java:130)
	at io.netty.channel.socket.nio.NioDatagramChannel.doBind0(NioDatagramChannel.java:201)
	at io.netty.channel.socket.nio.NioDatagramChannel.doBind(NioDatagramChannel.java:196)
	at io.netty.channel.AbstractChannel$AbstractUnsafe.bind(AbstractChannel.java:562)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.bind(DefaultChannelPipeline.java:1334)
	at io.netty.channel.AbstractChannelHandlerContext.invokeBind(AbstractChannelHandlerContext.java:506)
	at io.netty.channel.AbstractChannelHandlerContext.bind(AbstractChannelHandlerContext.java:491)
	at io.netty.channel.DefaultChannelPipeline.bind(DefaultChannelPipeline.java:973)
	at io.netty.channel.AbstractChannel.bind(AbstractChannel.java:260)
	at io.netty.bootstrap.AbstractBootstrap$2.run(AbstractBootstrap.java:356)
	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.base/java.lang.Thread.run(Thread.java:833)

[Source Server Query] Encoding issue

I'm having an issue where if the server hostname contains the โ”‚ character (\u2502), SourceQueryClient.getServerInfo() returns it as รข??. Is there a way to specify the encoding used? I'm not sure how to resolve this problem.

NumberFormatException when parsing StoreAppPackageGroup

Exception:

java.util.concurrent.CompletionException: com.google.gson.JsonSyntaxException: java.lang.NumberFormatException: For input string: "default"
	at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:314) ~[na:na]
	at java.base/java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:319) ~[na:na]
	at java.base/java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:645) ~[na:na]

Findings:

The current data type for display_type (under package_groups) is int, but for some apps, it can be a string.

App ID: 46790 (display_type is a string)

"package_groups": [
		{
			"name": "default",
			"title": "Buy Armada 2526",
			"description": "",
			"selection_text": "Select a purchase option",
			"save_text": "",
			"display_type": "default",
			"is_recurring_subscription": "false",
			"subs": [
				{
					"packageid": 19228,
					"percent_savings_text": "",
					"percent_savings": 0,
					"option_text": "Armada 2526 - P389.95",
					"option_description": "",
					"can_get_free_license": "0",
					"is_free_license": false,
					"price_in_cents_with_discount": 38995
				}
			]
		}
	]

App ID: 550 (display_type is an integer)

package_groups": [

    {
        "name": "default",
        "title": "Buy Left 4 Dead 2",
        "description": "",
        "selection_text": "Select a purchase option",
        "save_text": "",
        "display_type": 0,
        "is_recurring_subscription": "false",
        "subs": [
            {
                "packageid": 2481,
                "percent_savings_text": "",
                "percent_savings": 0,
                "option_text": "Left 4 Dead 2 - P289.95",
                "option_description": "",
                "can_get_free_license": "0",
                "is_free_license": false,
                "price_in_cents_with_discount": 28995
            },
            {
                "packageid": 220726,
                "percent_savings_text": "",
                "percent_savings": 0,
                "option_text": "Left 4 Dead 2 - Commercial License - P289.95",
                "option_description": "",
                "can_get_free_license": "0",
                "is_free_license": false,
                "price_in_cents_with_discount": 28995
            }
        ]
    }

]

Solution: Convert StoreAppPackageGroup.displayType data type to String

[Dota 2 Web API]wrong int type in pojo object

Verify

for example,the match_Id filed. This is easy to test and verify:

  1. load match history
https://api.steampowered.com/IDOTA2Match_570/GetMatchHistory/v1?account_id=125038361&key=XXXX
  1. from the response,we can determine match_id is a long type ,for example
{
    "match_id": 3429744798,
    "match_seq_num": 2989122942,
    ...
},
{
    "match_id": 3428039636,
    "match_seq_num": 2987709399
	...
}

The problem

int matchId= -1234;
Dota2MatchDetails details = matchInterface.getMatchDetails(matchId).get();

not work,getMatchDetails dont accept negative ,see AbstractWebRequest.urlParam

Dota2MatchHistoryCriteria dota2MatchHistoryCriteria = new Dota2MatchHistoryCriteria();
dota2MatchHistoryCriteria.accountId(125038361L);
Dota2MatchHistory matchHistory = matchInterface.getMatchHistory(dota2MatchHistoryCriteria).get();

matchHistory.getMatches().forEach(matchHistoryInfo ->{
    if(matchHistoryInfo.getMatchId() < 0){
        System.out.println("bug");// negative 
    }
});

Fix javadoc typo

Due to a mishap on refactoring, javadoc comments containing the word 'server' have been accidentally replaced with 'logger'. Need to fix this.

Affected classes:

  • SourceQueryClient.java
  • RequestStatus.java
  • MasterServerFilter.java
  • MasterServerQueryClient.java

Querying gameservers for A2S_INFO in Steam's network

A while ago Valve implemented the SDR for their TF2 official gameservers, this means the servers are no longer publicly queryable for information. See https://www.teamfortress.com/post.php?id=100538

When I currently ask the TF2 gamecoordinator for a list of gameservers, the official servers are returned, but they return an IP address which is probably only accessible from inside the steam network.

Is there any way to query these Gameservers for the A2S_INFO (e.g. by logging into the steam network)?

As an example, this is an official servers, which is only available from inside the Steam network:
{"addr":"169.254.173.78:41744","gameport":41744,"steamid":"90159483364902919","name":"Valve Matchmaking Server (Virginia srcds2015-iad1 #35)","appid":440,"gamedir":"tf","version":"7182415","product":"tf","region":255,"players":0,"max_players":6,"bots":0,"map":"mvm_ghost_town","secure":true,"dedicated":true,"os":"l","gametype":"hidden,mvm,valve"}

[COC WebAPI] Implement /locations/{locationId}/rankings/clans-versus

Description:
Get clan versus rankings for a specific location

Implementation Details:

Interface: CocLocations

Method: getClanVsRankingsForLoc()

Return Type: CocLocationClanVsRanks

JSON Schema:

{
  "items": [
    {
      "tag": "string",
      "name": "string",
      "location": {
        "id": 0,
        "name": "string",
        "isCountry": true
      },
      "badgeUrls": {
        "small": "string",
        "large": "string",
        "medium": "string"
      },
      "clanLevel": 0,
      "clanPoints": 0,
      "clanVersusPoints": 0,
      "members": 0,
      "rank": 0,
      "previousRank": 0
    }
  ]
}

Parameters:

Parameter Value Description Parameter Type Data Type
location id Identifier of the location to retrieve. path string
limit Limit the number of items returned in the response. query integer
after Return only items that occur after this marker. After marker can be found from the response, inside the 'paging' property. Note that only after or before can be specified for a request, not both. query integer
before Return only items that occur before this marker. Before marker can be found from the response, inside the 'paging' property. Note that only after or before can be specified for a request, not both. query integer

Dependency Conflict with AHC

Getting runtime errors due to netty dependency conflicts with AHC:

java.lang.NoSuchMethodError: io.netty.channel.DefaultChannelId.newInstance()Lio/netty/channel/DefaultChannelId

AHC 2.0.x is still using Netty 4.0.x. Will have to temporarily switch to AHC 2.1.x-alpha build as its using the latest netty version.

MasterServerFilter needs to be reimplemented

Issue: When an instance of MasterServerFilter is re-used and it's existing properties gets updated at runtime, those properties are appended into the underlying string buffer resulting into duplicates.

Consider the following code snippet:

public class MasterServerQueryClientIT {

    private static final Logger log = LoggerFactory.getLogger(MasterServerQueryClientIT.class);

    private MasterServerQueryClient client = new MasterServerQueryClient();

    @Test
    @DisplayName("Test query ")
    void test01() {
        final MasterServerFilter filter = MasterServerFilter.create().dedicated(true);
        final int[] appIds = new int[] {550, 440, 730};
        getServerList(appIds, MasterServerRegion.REGION_ALL, MasterServerType.SOURCE, filter);
    }

    private Map<Integer, Vector<InetSocketAddress>> getServerList(int[] appIds, MasterServerRegion region, MasterServerType type, MasterServerFilter filter) {
        Map<Integer, Vector<InetSocketAddress>> addressMap = new HashMap<>();
        log.info("Retrieving server list: ");
        for (int appId : appIds) {
            //update filter for appId
            filter = filter.appId(appId);
            log.info("App ID: {}, Filter: {}", appId, filter);
            //Vector<InetSocketAddress> res = client.getServerList(type, region, filter).join();
            //addressMap.put(appId, res);
        }
        return addressMap;
    }
}

Output

21:17:48.025 [main] INFO MasterServerQueryClientIT - Retrieving server list: 
21:17:48.026 [main] INFO MasterServerQueryClientIT - App ID: 550, Filter: \dedicated\1\appId\550
21:17:48.026 [main] INFO MasterServerQueryClientIT - App ID: 440, Filter: \dedicated\1\appId\550\appId\440
21:17:48.026 [main] INFO MasterServerQueryClientIT - App ID: 730, Filter: \dedicated\1\appId\550\appId\440\appId\730

Solution:

Re-implement the MasterServerFilter to use an internal map instead of a StringBuffer to avoid duplicates.

Missing implementation for Steam ReportCheatData

ReportCheatData does not have any implementation.

  • Create interface SteamCheatReportingService
  • Add method reportCheatData into SteamCheatReportingService
  • Add implementation for ReportCheatData class

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.