War API

Through this API supplied by the game developers, anyone can get raw information about the current Foxhole World Conquest, the aim of this page is to work upon what the 'README' supplies by providing more examples, explaining some nuances, providing additional resources, etc.

The Developer's API Documentation is available here: https://github.com/clapfoot/warapi (hereafter refered to as the 'documentation').

## Data Access and Format

### Access

All data from the API is accessed via 'HTTPS', the most basic API call here is for the War State: `https://war-service-live.foxholeservices.com/api/worldconquest/war`

#### Rate Limiting and Caching

The game developers ask *"...ask that you respect the caching headers as returned by the API. They reflect the lifetime of the data returned in the body of the request and requests sooner than the cache expiry will return the same data."*

This is explained some more here: Utlising ETag for Rate Limiting

### Format

All data from the API is returned in 'JSON'; for example, the API above can return the following:

```
{
 "warId" : "9b33b555-e587-4915-89a5-50eb37f2949d",
 "warNumber" : 33,
 "winner" : "NONE",
 "conquestStartTime" : 1563291629686,
 "conquestEndTime" : null,
 "resistanceStartTime" : null,
 "requiredVictoryTowns" : 20
}

```
This data will likely come back as part of a whole https request, the data will be within the 'body' of the response which also includes other properties such as 'headers'.

```
{
 "statusCode": 200,
 "headers": {
 "etag": ""616"",
 },
 "body": {
 ...API data here...
 }
}

```
Status Codes can be for example:

* 200: Success
* 304: etag supplied, and data has not changed since
* 5XX: Internal Server Error

## Available Data

Note, that all data made available via the APIs do not supply anything typically unavailable to one side; e.g. they do not supply Bunker Base locations, but do provide the position and faction of all Town Halls.

### Shards

Data is made available for both the primary shard, and the secondary one, how to access each is detailed in the documentation.

### War Data

#### War State

API: `/war`

This API will give you overall information about the war itself; it will not change until the end of the war at which the end time, resistance start time, and winner properties, will be populated.

```
{
 "warId" : "9b33b555-e587-4915-89a5-50eb37f2949d",
 "warNumber" : 33,
 "winner" : "NONE",
 "conquestStartTime" : 1563291629686,
 "conquestEndTime" : null,
 "resistanceStartTime" : null,
 "requiredVictoryTowns" : 20
}

```

### Map Related Data

Most likely the data you're the most interested in; this will detail both geographic map information such as where items are named, and where structures are placed and owned by which faction.

#### Map Names

API: `/maps`

The below is an example, with just 3 items, rather than all 37 regions; the API will return active regions in the current war.

```
[
 "TheFingersHex",
 "GreatMarchHex",
 "TempestIslandHex"
]

```

#### Map War Report

API: `warReport/:mapName`

This will give you details on the enlistments, casualties, and day of the war in a region.

Note, the enlistments here are unique players per map as per the API; a player deploying to two regions will count to both's 'totalEnlistments' value; therefore totaling the enlistments for all maps would not report unique players for the war, but significantly more.

The Home Regions reset once a real-world day, and are again the unique players that have logged in.

```
{
 "totalEnlistments" : 148,
 "colonialCasualties" : 202,
 "wardenCasualties" : 222,
 "dayOfWar" : 2
}

```

#### Map Item Data

Both forms of 'Map Item Data' return the same format of JSON as exampled on the documentation 'Map Data Schema' which consists of some region data, and then an array of 'map items' which are each objects (these map items and the property they are contained in, differ between the APIs).

There is a relationship between both 'dynamic' and 'static' data, for example a Town Hall's label (e.g. 'Allsight'), and the position of the Town Hall structure itself; however they do not share the exact same x/y positioning.

```
{
 "regionId": 40,
 "scorchedVictoryTowns": 0,
 "mapItems": [...],
 "mapTextItems": [...],
 "lastUpdated": 1641769760480,
 "version": 40
}

```

##### Map Static Data

API: `maps/:mapName/static`

This will return text labels of `"Major"` and `"Minor"` types for the region such as Town Hall names (e.g. 'Abandoned Ward') and areas like a field or road (e.g. 'Sunhaven Gateway').

This is returned within `body.mapTextItems` Array

```
{
 "text" : "Abandoned Ward",
 "x" : 0.410076,
 "y" : 0.4957782,
 "mapMarkerType": "Major"
}

```

##### Map Dynamic Data

API: `maps/:mapName/dynamic/public`

This is most likely the data that you're after; every map structure publicly known to both factions is reported here, this is what drives any website you've seen that renders the world map and its structures.

This is returned within `body.mapItems` Array

```
{
 "teamId": "COLONIALS",
 "iconType": 58,
 "x": 0.58287543,
 "y": 0.14814812,
 "flags": 41
}

```

* Team Id is of either `"NONE"`, `"WARDENS"`, `"COLONIALS"`
* Icon Type: A full list is available on the documentation here, and clarifications in Map Data Further Explanation
* X/Y: See Using X and Y
* Flags: See Flags

## Additional Information

### World Extents

In the documentation, the developers detail the extent of the 'world', now contrary to the wording this is actually the extents of a single hex/region and is measured in centimeters.

At time of writing these extents are:

* `WorldExtent.Minimum = (-109199.999997, -94499.99999580906968410989)`
* `WorldExtent.Maximum = (109199.999997, 94499.99999580906968410989)`

### Using X and Y

The X and Y values from 'map items' provided by the map APIs are values between zero and one, these essentially describe the percentage across, and down a hex that they are positioned, e.g. `x: 0.25, y: 0.5` would mean the item should be positioned one quarter or 25% from the left of the hex, and half way down; see image.

Combining this with World Extents allows you to have a highly accurately proportioned hexagon, and positioned structures/items within; however it is not necessary for generating a graphic of a hex.

### Utlising ETag for Rate Limiting

Some APIs will respond with an `etag` in their headers such as `""616""` and can (and should) be sent in future requests, if the API then responsed with a 'statusCode' of 304 then the data you last requested is still valid.

To send this 'etag' back into the API you can add it as a header e.g: `"If-None-Match": ""616""`

This principle is also outlined on the Mozilla Documentation.

### Map Data Further Explanation

There are some nuances around the Map data that is made available, both in its flow and in the data itself, those will be explained here.

#### Town Halls Change Ids

At the time of writing, the Ids for all Town Halls are actually spread across 3; one for each tier which are 56, 57, and 58. Therefore if you write something that cares about ownership and not tier, you will need to treat these Ids as the same.

Additionally as detailed below, Relic Bases are spread across 3 different Ids for a different reason.

#### Confusing Map Icon Ids

On the documentation the developers detail the value for `iconType` in the section 'Map Icons' however not all of them match the language used today, we'll list some here to help you along:

* ID 22 - Fuel Field - This is not the 'Oil Well' present in the game at time of writing, and is an old feature of the game and is unused.
	+ The actual Oil Well is ID 41
* ID 27 - Special Base - This is the Keep structure, which don't (at time of writing) count to victory or ownership over parts of a region (like a safehouse).
	+ For example there is a Keep on the Warden Dam in 'Hown County' but 'Westgate Keep' is actually controlled by the Relic to the West of the Keep itself
* ID 33 - Storage Facility - This is the Storage Depot building
* ID 35 - Garrison Station - This is the Safehouse building
* ID 45, 46, 47 - Relic Base - These are the Relic bases on the map which also count to region control; there are 3 different kinds of Relic so they do not pertain to tiers, just structure design.

#### War State Changes

The war state appears to change in the following instances:

* War has been won
	+ Sets the 'winner', 'conquestEndTime', and 'resistanceStartTime' fields
* Next War has been setup (live in API, but not live for players)
	+ New 'warId' and 'warNumber' set
	+ Resets 'winner' to `"NONE"`, and 'conquestStartTime', 'conquestEndTime', and 'resistanceStartTime' all to `null`
	+ *It is likly 'requiredVictoryTowns' also changes, but this is unknown by writer at this time*
* Next War made live for players
	+ Sets 'conquestStartTime'

#### Flags

Once you've started looking at the data for a while, you'll notice the dynamic data has a field called 'flags' as a singular number for instance `"flags": 41` which is initially confusing as the value is a single number, but worded as if it is multiple things...which it is.

***Warning: Things get very technical***

This value of 41 makes use of 'bit masking' & 'bit shifting' princpiples to basically store several true/false values in a single number. When we take the base-10 value of 41 and convert it to Binary, we get `101001` which to not go too deep into binary is (from left to right) 32 + 8 + 1 = 41.

These three 1's in the binary corrospond to a different 'flag' in the documentation, however the documentation details these values in base-16 known as hexadecimal e.g. the value 20 is actually 'two-zero' and represents the base-10 value of 14 or binary `10100`

```
 41 = 101001 - A claimed Colonial T3 Town Hall & Victory Point

0x1 (1) = 000001 - isVictoryBase
0x4 (4) = 000100 - isBuildSite
0x10 (16) = 010000 - isScorched
0x20 (32) = 100000 - isTownClaimed
(b16)(b10) (b2)

```
Using Binary Logic such as Bit-Masking or Bit-Shifting, you can write some code to assert that the corrosponding BIT for the 'flags' value you get, is a 1 or 0 for the condition you want to know about, aka check that the 1st bit from the right is 1 for Victory Point, and the 6th bit from the right is 1 for Town Claimed.

Any other map flags not listed here are for internal use only, and should not be relied upon as they may be removed at any time.

## Known Issue(s)

There are a few known issues with the API that those that use it should be aware of, for a full list (or to add your own findings) you can see the issues list here: Open Issues

### Notable issue(s)

#### Server Restarts

Issue Link: https://github.com/clapfoot/warapi/issues/92

This particular issue explains that when the servers restart, most of the data from the dynamic map API goes away but is still returned successfully; which can cause issues in what you use this data for e.g. for building a history.

We've mentioned it here as it'll be the one you'll most likly be affected the most by, but be equally unaware of.

#### War Days de-sync

Issue Link: https://github.com/clapfoot/warapi/issues/81

This issue is in reguards to not all maps from the 'Map War Report' API having the same 'days' value, which appears to not get reset (or incorrectly reset); caused by server events such as restarts or crashes.