Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Setup webserver and frontend stuff, and fix some minor issues
- Loading branch information
1 parent
5626821
commit 17e9ff5
Showing
147 changed files
with
23,511 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
73 changes: 73 additions & 0 deletions
73
src/main/java/com/derpthemeus/runeCoach/jetty/ChampionInfoHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package com.derpthemeus.runeCoach.jetty; | ||
|
||
import com.derpthemeus.runeCoach.DDragonManager; | ||
import com.derpthemeus.runeCoach.RuneCoach; | ||
import com.google.gson.Gson; | ||
import org.eclipse.jetty.http.MimeTypes; | ||
import org.eclipse.jetty.server.Request; | ||
import org.eclipse.jetty.server.handler.AbstractHandler; | ||
import org.hibernate.Session; | ||
import org.hibernate.query.Query; | ||
|
||
import javax.servlet.ServletException; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
import java.io.IOException; | ||
import java.util.AbstractMap; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.stream.Collectors; | ||
|
||
public class ChampionInfoHandler extends AbstractHandler { | ||
// How long data should be cached for (in milliseconds) | ||
private static final int CACHE_TIME = 1000 * 60 * 60; | ||
|
||
private final List<String> championIds; | ||
private final Gson gson = new Gson(); | ||
|
||
// Cached JSON responses for champions. Shorts are champion IDs, Longs are timestamps, Strings are JSON | ||
private final Map<Short, Map.Entry<Long, String>> cache = new HashMap<>(); | ||
|
||
|
||
public ChampionInfoHandler() throws IOException { | ||
DDragonManager.ChampionList champions = DDragonManager.getChampionList(DDragonManager.getLatestVersion()); | ||
championIds = champions.data.values().stream().map(champion -> champion.key).collect(Collectors.toList()); | ||
} | ||
|
||
@Override | ||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { | ||
if (!championIds.contains(request.getParameter("championId"))) { | ||
response.setContentType(MimeTypes.Type.TEXT_PLAIN.asString()); | ||
// TODO use a raw message instead of an HTML page | ||
response.sendError(HttpServletResponse.SC_NOT_FOUND, "Error: champion with specified ID does not exist"); | ||
baseRequest.setHandled(true); | ||
return; | ||
} | ||
|
||
short championId = Short.parseShort(request.getParameter("championId")); | ||
Map.Entry<Long, String> cacheEntry = cache.get(championId); | ||
|
||
if (cacheEntry == null || System.currentTimeMillis() - cacheEntry.getKey() > CACHE_TIME) { | ||
try (Session session = RuneCoach.getSessionFactory().openSession()) { | ||
// TODO allow patch to be specified through config, or automatically switch to latest patch once enough data has been aggregated | ||
Query query = session.createQuery("SELECT NEW MAP(perkScore.perkId AS perkId, perkScore.score AS score, perkScore.scoreType AS type)" + | ||
" FROM PerkScoreEntity AS perkScore WHERE patch=:patch AND championId=:championId AND games>200 AND scoreType!='RAW'") | ||
.setParameter("patch", "7.24").setParameter("championId", championId); | ||
List<Map> scores = query.getResultList(); | ||
|
||
String json = gson.toJson(scores); | ||
|
||
response.setStatus(HttpServletResponse.SC_OK); | ||
response.getWriter().write(json); | ||
baseRequest.setHandled(true); | ||
|
||
cache.put(championId, new AbstractMap.SimpleEntry<>(System.currentTimeMillis(), json)); | ||
} | ||
} else { | ||
response.setStatus(HttpServletResponse.SC_OK); | ||
response.getWriter().write(cacheEntry.getValue()); | ||
} | ||
baseRequest.setHandled(true); | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
src/main/java/com/derpthemeus/runeCoach/jetty/RuneCoachWebServer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package com.derpthemeus.runeCoach.jetty; | ||
|
||
import org.eclipse.jetty.server.Server; | ||
import org.eclipse.jetty.server.handler.ContextHandler; | ||
import org.eclipse.jetty.server.handler.HandlerCollection; | ||
import org.eclipse.jetty.server.handler.ResourceHandler; | ||
import org.eclipse.jetty.util.resource.Resource; | ||
|
||
public class RuneCoachWebServer { | ||
private final Server jettyServer; | ||
|
||
public RuneCoachWebServer(int port) throws Exception { | ||
jettyServer = new Server(port); | ||
|
||
ResourceHandler staticHandler = new ResourceHandler(); | ||
staticHandler.setDirectoriesListed(false); | ||
staticHandler.setResourceBase(Resource.newClassPathResource("frontend_static/").toString()); | ||
|
||
ContextHandler championInfoHandler = new ContextHandler("/getChampionInfo"); | ||
championInfoHandler.setHandler(new ChampionInfoHandler()); | ||
|
||
ContextHandler staticDataHandler = new ContextHandler("/getStaticData"); | ||
staticDataHandler.setHandler(new StaticDataHandler()); | ||
|
||
ContextHandler runesHandler = new ContextHandler("/getRunes"); | ||
runesHandler.setHandler(new RunesHandler()); | ||
|
||
HandlerCollection handlers = new HandlerCollection( | ||
staticHandler, championInfoHandler, staticDataHandler, runesHandler | ||
); | ||
jettyServer.setHandler(handlers); | ||
jettyServer.start(); | ||
} | ||
} |
72 changes: 72 additions & 0 deletions
72
src/main/java/com/derpthemeus/runeCoach/jetty/RunesHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package com.derpthemeus.runeCoach.jetty; | ||
|
||
import com.derpthemeus.runeCoach.DDragonManager; | ||
import com.google.gson.Gson; | ||
import com.google.gson.JsonArray; | ||
import com.google.gson.JsonObject; | ||
import org.eclipse.jetty.server.Request; | ||
import org.eclipse.jetty.server.handler.AbstractHandler; | ||
|
||
import javax.servlet.ServletException; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
import java.io.IOException; | ||
import java.io.InputStreamReader; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
public class RunesHandler extends AbstractHandler { | ||
|
||
private String cachedResponse; | ||
|
||
public RunesHandler() throws IOException { | ||
Gson gson = new Gson(); | ||
JsonObject builderRunes = gson.toJsonTree(gson.fromJson(new InputStreamReader(getClass().getResourceAsStream("/builder-runes.json")), Object.class)).getAsJsonObject(); | ||
JsonArray lcuRunes = gson.toJsonTree(gson.fromJson(new InputStreamReader(getClass().getResourceAsStream("/LCU-runes.json")), Object.class)).getAsJsonArray(); | ||
DDragonManager.StyleInfo[] ddragonRunes = DDragonManager.getRuneInfo(DDragonManager.getLatestVersion()); | ||
|
||
// Map LCU runes by ID | ||
Map<Integer, JsonObject> lcuMappedRunes = new HashMap<>(); | ||
// The first element is a template, not an actual rune | ||
for (int i = 1; i < lcuRunes.size(); i++) { | ||
JsonObject rune = lcuRunes.get(i).getAsJsonObject(); | ||
lcuMappedRunes.put(rune.get("id").getAsInt(), rune); | ||
} | ||
|
||
builderRunes.getAsJsonArray("styles").forEach(builderStyleEl -> { | ||
JsonObject builderStyle = builderStyleEl.getAsJsonObject(); | ||
// Copy style IDs from DDragon | ||
for (DDragonManager.StyleInfo ddragStyle : ddragonRunes) { | ||
if (builderStyle.get("name").getAsString().equals(ddragStyle.name)) { | ||
builderStyle.getAsJsonObject().addProperty("id", ddragStyle.id); | ||
break; | ||
} | ||
} | ||
|
||
// Copy formatted descriptions from LCU | ||
builderStyle.getAsJsonArray("slots").forEach(slot -> { | ||
slot.getAsJsonObject().getAsJsonArray("runes").forEach(runeEl -> { | ||
JsonObject builderRune = runeEl.getAsJsonObject(); | ||
JsonObject lcuRune = lcuMappedRunes.get(builderRune.get("runeId").getAsInt()); | ||
|
||
String longDesc = lcuRune.get("longDesc").getAsString(); | ||
String shortDesc = lcuRune.get("shortDesc").getAsString(); | ||
|
||
builderRune.addProperty("longDescription", longDesc); | ||
builderRune.addProperty("shortDescription", shortDesc); | ||
}); | ||
}); | ||
|
||
// TODO bonuses (secondary styles) | ||
}); | ||
|
||
this.cachedResponse = gson.toJson(builderRunes); | ||
} | ||
|
||
@Override | ||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { | ||
response.setStatus(HttpServletResponse.SC_OK); | ||
response.getWriter().write(cachedResponse); | ||
baseRequest.setHandled(true); | ||
} | ||
} |
79 changes: 79 additions & 0 deletions
79
src/main/java/com/derpthemeus/runeCoach/jetty/StaticDataHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package com.derpthemeus.runeCoach.jetty; | ||
|
||
import com.derpthemeus.runeCoach.DDragonManager; | ||
import com.derpthemeus.runeCoach.RuneCoach; | ||
import com.derpthemeus.runeCoach.hibernate.PerkScoreEntity; | ||
import com.derpthemeus.runeCoach.hibernate.TagEntity; | ||
import com.google.gson.Gson; | ||
import com.google.gson.JsonObject; | ||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
import org.eclipse.jetty.server.Request; | ||
import org.eclipse.jetty.server.handler.AbstractHandler; | ||
import org.hibernate.Session; | ||
import org.hibernate.query.Query; | ||
|
||
import javax.servlet.ServletException; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
import java.io.IOException; | ||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
/** | ||
* Returns a champion list, tag list, the best tag for each rune, and announcement messages | ||
*/ | ||
public class StaticDataHandler extends AbstractHandler { | ||
|
||
private String cachedResponse; | ||
private final Gson gson = new Gson(); | ||
private final Logger logger = LogManager.getLogger(); | ||
|
||
public StaticDataHandler() throws IOException { | ||
updateCachedResponse(); | ||
} | ||
|
||
@Override | ||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { | ||
response.setStatus(HttpServletResponse.SC_OK); | ||
response.getWriter().write(cachedResponse); | ||
baseRequest.setHandled(true); | ||
} | ||
|
||
// TODO automatically update (also requires updating DDragonManager, since it currently caches latest version) | ||
private void updateCachedResponse() throws IOException { | ||
logger.info("Updating static data..."); | ||
String ddragVersion = DDragonManager.getLatestVersion(); | ||
|
||
JsonObject obj = new JsonObject(); | ||
obj.addProperty("announcementMessage", System.getenv("ANNOUNCEMENT_MESSAGE")); | ||
obj.addProperty("announcementLink", System.getenv("ANNOUNCEMENT_LINK")); | ||
obj.addProperty("ddragonVersion", ddragVersion); | ||
obj.add("champions", gson.toJsonTree(DDragonManager.getChampionList(ddragVersion).data.values().toArray())); | ||
try (Session session = RuneCoach.getSessionFactory().openSession()) { | ||
// Get tags | ||
Map<Short, TagEntity> tags = new HashMap<>(); | ||
for (TagEntity tag : (List<TagEntity>) session.createQuery("FROM TagEntity").getResultList()) { | ||
tags.put(tag.getTagId(), tag); | ||
} | ||
obj.add("tags", gson.toJsonTree(tags)); | ||
|
||
// Get best tags for each perk | ||
List<PerkScoreEntity> bestTags = new ArrayList<>(); | ||
// TODO do some fancy HQL stuff here instead of iterating over perk IDs | ||
for (Short perkId : DDragonManager.getPerkAndStyleIds(DDragonManager.getLatestVersion())) { | ||
// TODO allow patch to be specified through config, or automatically switch to latest patch once enough data has been aggregated | ||
Query query = session.createQuery("SELECT NEW MAP(perkScore.perkId AS perkId, perkScore.score AS score, -perkScore.championId AS tagId) " + | ||
"FROM PerkScoreEntity AS perkScore WHERE games>200 AND championId<0 AND patch=:patch AND scoreType='RELATIVE' AND perkId=:perkId ORDER BY score DESC") | ||
.setParameter("patch", "7.24").setParameter("perkId", perkId); | ||
bestTags.addAll(query.setMaxResults(2).getResultList()); | ||
} | ||
obj.add("bestTags", gson.toJsonTree(bestTags)); | ||
} | ||
|
||
cachedResponse = gson.toJson(obj); | ||
logger.info("Updated static data"); | ||
} | ||
} |
Oops, something went wrong.