Skip to content

Commit 97b24ff

Browse files
committed
convert to ToonHQ invasion data
toon.plus is dead
1 parent 69329bc commit 97b24ff

File tree

2 files changed

+158
-43
lines changed

2 files changed

+158
-43
lines changed

src/main/java/lol/hyper/customlauncher/invasions/Invasion.java

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public class Invasion implements Comparable<Invasion> {
3636
/**
3737
* The end time reported by the API.
3838
*/
39-
public ZonedDateTime endTime;
39+
private ZonedDateTime endTime;
4040
/**
4141
* The current cog defeated count.
4242
*/
@@ -49,6 +49,10 @@ public class Invasion implements Comparable<Invasion> {
4949
* Stores when we started to track this invasion locally.
5050
*/
5151
private final long cacheStartTime;
52+
/**
53+
* How fast the invasion is being defeated.
54+
*/
55+
private double defeatRate;
5256

5357
/**
5458
* Creates a new invasion.
@@ -102,6 +106,42 @@ public String getDistrict() {
102106
return district;
103107
}
104108

109+
/**
110+
* Get the defeat rate.
111+
*
112+
* @return The defeat rate.
113+
*/
114+
public double getDefeatRate() {
115+
return defeatRate;
116+
}
117+
118+
/**
119+
* Set the defeat rate.
120+
*
121+
* @param defeatRate The new defeat rate.
122+
*/
123+
public void setDefeatRate(double defeatRate) {
124+
this.defeatRate = defeatRate;
125+
}
126+
127+
/**
128+
* Get when the invasion will end roughly.
129+
*
130+
* @return When it ends.
131+
*/
132+
public ZonedDateTime getEndTime() {
133+
return endTime;
134+
}
135+
136+
/**
137+
* Set when the invasion will end.
138+
*
139+
* @param endTime The end time.
140+
*/
141+
public void setEndTime(ZonedDateTime endTime) {
142+
this.endTime = endTime;
143+
}
144+
105145
/**
106146
* Updates the cogs defeated.
107147
*

src/main/java/lol/hyper/customlauncher/invasions/InvasionTrackerPanel.java

Lines changed: 117 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import lol.hyper.customlauncher.tools.JSONUtils;
2626
import org.apache.logging.log4j.LogManager;
2727
import org.apache.logging.log4j.Logger;
28+
import org.json.JSONArray;
2829
import org.json.JSONObject;
2930

3031
import javax.swing.Timer;
@@ -36,6 +37,7 @@
3637
import java.time.Instant;
3738
import java.time.LocalDateTime;
3839
import java.time.ZoneId;
40+
import java.time.ZonedDateTime;
3941
import java.time.temporal.ChronoUnit;
4042
import java.util.List;
4143
import java.util.*;
@@ -48,7 +50,15 @@ public class InvasionTrackerPanel extends JPanel {
4850
/**
4951
* All current invasions saved locally.
5052
*/
51-
private final Map<String, Invasion> invasions = new HashMap<>();
53+
private final Map<Integer, Invasion> invasions = new HashMap<>();
54+
/**
55+
* Cog ID map.
56+
*/
57+
private final Map<Integer, String> cogMap = new HashMap<>();
58+
/**
59+
* District ID map.
60+
*/
61+
private final Map<Integer, String> districtMap = new HashMap<>();
5262
/**
5363
* The table for displaying invasions.
5464
*/
@@ -121,6 +131,23 @@ public InvasionTrackerPanel(ConfigHandler configHandler) {
121131
timer.setDelay(500);
122132
timer.start();
123133

134+
// fetch ToonHQ's data
135+
logger.info("Fetching ToonHQ district data...");
136+
JSONArray districts = JSONUtils.requestJSONArray("https://toonhq.org/api/districts/");
137+
logger.info("Fetching ToonHQ cog data...");
138+
JSONArray cogs = JSONUtils.requestJSONArray("https://toonhq.org/api/cogs/");
139+
140+
if (districts == null || cogs == null) {
141+
logger.info("No districts or cogs found");
142+
logger.info("Cog data: {}", cogs);
143+
logger.info("District data: {}", districts);
144+
isDown = true;
145+
return;
146+
}
147+
148+
updateDistrictMap(districts);
149+
updateCogMap(cogs);
150+
124151
// start the timer for reading the API
125152
startInvasionRefresh();
126153
}
@@ -132,7 +159,7 @@ private void updateInvasionListGUI() {
132159
invasionTableModel.setRowCount(0);
133160
// create a separate list of all the invasions
134161
List<Invasion> sortedInvasions = new ArrayList<>();
135-
for (Map.Entry<String, Invasion> entry : invasions.entrySet()) {
162+
for (Map.Entry<Integer, Invasion> entry : invasions.entrySet()) {
136163
sortedInvasions.add(entry.getValue());
137164
}
138165
// sort this new list alphabetically
@@ -149,7 +176,7 @@ private void updateInvasionListGUI() {
149176
timeLeft = "Mega Invasion";
150177
} else {
151178
cogs = invasion.getCogsDefeated() + "/" + invasion.getCogsTotal();
152-
timeLeftSeconds = ChronoUnit.SECONDS.between(LocalDateTime.now(), invasion.endTime);
179+
timeLeftSeconds = ChronoUnit.SECONDS.between(LocalDateTime.now(), invasion.getEndTime());
153180
if (timeLeftSeconds <= 0) {
154181
timeLeft = "Ending soon...";
155182
} else {
@@ -213,7 +240,7 @@ public void showNotification(Invasion invasion, boolean newInvasion) {
213240
* Make the request and handle the information it returns.
214241
*/
215242
private void makeRequest() {
216-
String INVASION_URL = "https://api.toon.plus/invasions";
243+
String INVASION_URL = "https://toonhq.org/api/invasions/1/";
217244
JSONObject lastResult = JSONUtils.requestJSON(INVASION_URL);
218245

219246
// if the request failed, stop the task
@@ -225,63 +252,111 @@ private void makeRequest() {
225252

226253
isDown = false; // make sure to set this to false since we can read the API
227254

228-
// iterate through each of the invasions (separate JSONs)
229-
Iterator<String> keys = lastResult.keys();
230-
while (keys.hasNext()) {
231-
String key = keys.next();
232-
// each key is stored as district/cogType
233-
String district = key.substring(0, key.indexOf('/'));
234-
// if we do not have that invasion stored, create a new invasion object
235-
// and add it to the list
236-
if (!invasions.containsKey(district)) {
237-
JSONObject temp = lastResult.getJSONObject(key);
238-
String cogType = temp.getString("Type");
239-
int cogsDefeated = temp.getInt("CurrentProgress");
240-
int cogsTotal = temp.getInt("MaxProgress");
241-
boolean megaInvasion = temp.getBoolean("MegaInvasion");
242-
Invasion newInvasion = new Invasion(district, cogType, cogsTotal, megaInvasion);
255+
// iterate through each of the invasions
256+
JSONArray invasionsArray = lastResult.getJSONArray("invasions");
257+
for (int i = 0; i < invasionsArray.length(); i++) {
258+
JSONObject invasion = invasionsArray.getJSONObject(i);
259+
int districtId = invasion.getInt("district");
260+
String districtName = districtMap.get(districtId);
261+
String cogType = cogMap.get(invasion.getInt("cog"));
262+
int cogsTotal = invasion.getInt("total");
263+
int cogsDefeated = invasion.getInt("defeated");
264+
double defeatRate = invasion.getDouble("defeat_rate");
265+
266+
// this is a new invasion that we are not tracking currently
267+
if (!invasions.containsKey(districtId)) {
268+
// store the information about it
269+
Invasion newInvasion = new Invasion(districtName, cogType, cogsTotal, false);
243270
newInvasion.updateCogsDefeated(cogsDefeated);
244-
newInvasion.endTime = Instant.parse(temp.getString("EstimatedCompletion")).atZone(ZoneId.systemDefault());
245-
invasions.put(district, newInvasion);
271+
newInvasion.setDefeatRate(defeatRate);
272+
invasions.put(districtId, newInvasion);
273+
274+
// show notification for it
246275
if (configHandler.showCogInvasionNotifications()) {
247276
showNotification(newInvasion, true);
248277
}
249-
logger.info("Tracking new invasion for {}. Cogs: {}/{}. ETA: {}", district, cogsDefeated, cogsTotal, newInvasion.endTime);
278+
279+
// calculate how long it has left (estimate)
280+
double secondsRemaining = (cogsTotal - cogsDefeated) / defeatRate;
281+
ZonedDateTime estimatedEnd = Instant.now().plusSeconds((long) secondsRemaining).atZone(ZoneId.systemDefault());
282+
newInvasion.setEndTime(estimatedEnd);
283+
284+
logger.info("Tracking new invasion for {}. Cogs: {}/{}", districtName, cogsDefeated, cogsTotal);
250285
} else {
251-
// if we already have it saved, update the information that we have saved already
252-
// we want to update the total cogs defeated and the end time
253-
Invasion tempInv = invasions.get(district);
254-
JSONObject temp = lastResult.getJSONObject(key);
255-
// ignore mega invasion cog count
256-
if (!temp.getBoolean("MegaInvasion")) {
257-
int cogsDefeated = temp.getInt("CurrentProgress");
258-
logger.info("Updating invasion details for {}. Cogs: {} -> {}. ETA: {}", district, tempInv.getCogsDefeated(), cogsDefeated, tempInv.endTime);
259-
tempInv.updateCogsDefeated(cogsDefeated);
260-
tempInv.endTime = Instant.parse(temp.getString("EstimatedCompletion")).atZone(ZoneId.systemDefault());
261-
}
286+
// update the information for the invasion
287+
Invasion tempInv = invasions.get(districtId);
288+
tempInv.updateCogsDefeated(cogsDefeated);
289+
tempInv.setDefeatRate(defeatRate);
290+
291+
// calculate how long it has left (estimate)
292+
double secondsRemaining = (cogsTotal - cogsDefeated) / defeatRate;
293+
ZonedDateTime estimatedEnd = Instant.now().plusSeconds((long) secondsRemaining).atZone(ZoneId.systemDefault());
294+
tempInv.setEndTime(estimatedEnd);
295+
296+
logger.info("Updating invasion for {}. Cogs: {}/{}", districtName, cogsDefeated, cogsTotal);
262297
}
263298
}
264299

265300
// we look at the current invasion list and see if any invasions
266301
// are not on the invasion JSON (aka that invasion is gone)
267-
Iterator<Map.Entry<String, Invasion>> it = invasions.entrySet().iterator();
302+
Iterator<Map.Entry<Integer, Invasion>> it = invasions.entrySet().iterator();
268303
while (it.hasNext()) {
269-
Map.Entry<String, Invasion> pair = it.next();
270-
String cogType = pair.getValue().getCogType();
271-
String district = pair.getKey();
272-
// district/cog name
273-
String key = district + "/" + cogType;
274-
// if the invasion no longer exists on the API, remove it from our list
275-
if (!lastResult.has(key)) {
304+
Map.Entry<Integer, Invasion> pair = it.next();
305+
boolean isOnApi = false;
306+
for (int i = 0; i < invasionsArray.length(); i++) {
307+
JSONObject invasion = invasionsArray.getJSONObject(i);
308+
int districtId = invasion.getInt("district");
309+
if (pair.getKey().equals(districtId)) {
310+
isOnApi = true;
311+
}
312+
}
313+
314+
if (!isOnApi) {
276315
String savedDuration = (System.nanoTime() - pair.getValue().getCacheStartTime()) / 1000000000 + " seconds.";
277316
if (configHandler.showCogInvasionNotifications()) {
278317
showNotification(pair.getValue(), false);
279318
}
280319
it.remove();
281-
logger.info("Removing saved invasion for {}. Tracked for {}", district, savedDuration);
320+
logger.info("Removing saved invasion for {}. Tracked for {}", pair.getKey(), savedDuration);
282321
}
283322
}
284323
runs++;
285324
lastFetched = System.currentTimeMillis();
286325
}
326+
327+
/**
328+
* Update the district ID map from ToonHQ.
329+
*
330+
* @param data The JSON data from their API.
331+
*/
332+
private void updateDistrictMap(JSONArray data) {
333+
for (int i = 0; i < data.length(); i++) {
334+
JSONObject district = data.getJSONObject(i);
335+
int gameId = district.getInt("game");
336+
// make sure we pull TTR districts (id = 1)
337+
if (gameId == 1) {
338+
int id = district.getInt("id");
339+
String name = district.getString("name");
340+
districtMap.put(id, name);
341+
}
342+
}
343+
}
344+
345+
/**
346+
* Update the cog ID map from ToonHQ.
347+
*
348+
* @param data The JSON data from their API.
349+
*/
350+
private void updateCogMap(JSONArray data) {
351+
for (int i = 0; i < data.length(); i++) {
352+
JSONObject cog = data.getJSONObject(i);
353+
int gameId = cog.getInt("game");
354+
// make sure we pull TTR cogs (id = 1)
355+
if (gameId == 1) {
356+
int id = cog.getInt("id");
357+
String name = cog.getString("name");
358+
cogMap.put(id, name);
359+
}
360+
}
361+
}
287362
}

0 commit comments

Comments
 (0)