-
Notifications
You must be signed in to change notification settings - Fork 52
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a warding processor #3
base: master
Are you sure you want to change the base?
Changes from 1 commit
7e49bb5
2dab48f
c7be138
74474b1
a72fcaa
47530fb
510d6f2
063e10c
39c1428
cb76494
966684a
4141fad
55a0a45
57fa27b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,35 +2,61 @@ | |
|
||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.io.FileInputStream; | ||
import java.io.OutputStream; | ||
import java.net.InetSocketAddress; | ||
import com.sun.net.httpserver.HttpExchange; | ||
import com.sun.net.httpserver.HttpHandler; | ||
import com.sun.net.httpserver.HttpServer; | ||
|
||
public class Main { | ||
|
||
public static void main(String[] args) { | ||
try { | ||
|
||
if (args.length > 0 && args[0].equals("--file")) { System.exit(parse(args[1])); } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix brace spacing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To be honest, if you want to include the Main class, I'd rather have a proper arg-parsing, like Apache Commons CLI or similar. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current code only has the server case. i assume you added these additional startup methods to make testing easier. Previously, I just started the server and then used curl to POST a replay to it. Up to you if you want to keep them around. |
||
else if (args.length >0 && args[0].equals("--")) { System.exit(parseStream(System.in, System.out)); } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fix >0 spacing |
||
else { startServer(args); } | ||
} | ||
catch (Exception e) { | ||
e.printStackTrace(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do you need to catch the exception here? If we have one, we should crash since the startup is incorrect. |
||
} | ||
} | ||
|
||
public static void startServer(String[] args) throws Exception { | ||
HttpServer server = HttpServer.create(new InetSocketAddress(Integer.valueOf(args.length > 0 ? args[0] : "5600")), 0); | ||
server.createContext("/", new MyHandler()); | ||
server.setExecutor(java.util.concurrent.Executors.newFixedThreadPool(4)); | ||
server.start(); | ||
} | ||
|
||
public static void main(String[] args) throws Exception { | ||
HttpServer server = HttpServer.create(new InetSocketAddress(Integer.valueOf(args.length > 0 ? args[0] : "5600")), 0); | ||
server.createContext("/", new MyHandler()); | ||
server.setExecutor(java.util.concurrent.Executors.newFixedThreadPool(4)); | ||
server.start(); | ||
static int parseStream(InputStream is, OutputStream os) throws IOException { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think methods should have visibility declared. |
||
try { | ||
new Parse(is, os); | ||
} | ||
catch (Exception e) | ||
{ | ||
e.printStackTrace(); | ||
return -1; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. extra space |
||
} | ||
finally { | ||
is.close(); | ||
os.close(); | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
static int parse(String replay_file) throws Exception { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. call this parseFile There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use camelCase There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and call it fileName |
||
System.out.print(String.format("Parsing file %s", replay_file)); | ||
return parseStream(new FileInputStream(replay_file), System.out); | ||
} | ||
|
||
static class MyHandler implements HttpHandler { | ||
@Override | ||
public void handle(HttpExchange t) throws IOException { | ||
t.sendResponseHeaders(200, 0); | ||
InputStream is = t.getRequestBody(); | ||
OutputStream os = t.getResponseBody(); | ||
try { | ||
new Parse(is, os); | ||
} | ||
catch (Exception e) | ||
{ | ||
e.printStackTrace(); | ||
} | ||
os.close(); | ||
} | ||
@Override | ||
public void handle(HttpExchange t) throws IOException { | ||
t.sendResponseHeaders(200, 0); | ||
parseStream(t.getRequestBody(), t.getResponseBody()); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,9 +33,13 @@ | |
import java.util.Arrays; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Iterator; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.io.OutputStream; | ||
import yasp.processors.warding.OnWardCountered; | ||
import yasp.processors.warding.OnWardExpired; | ||
import yasp.processors.warding.OnWardPlaced; | ||
|
||
public class Parse { | ||
private class Entry { | ||
|
@@ -96,6 +100,7 @@ public Entry(Integer time) { | |
this.time = time; | ||
} | ||
} | ||
|
||
float INTERVAL = 1; | ||
float nextInterval = 0; | ||
Integer time = 0; | ||
|
@@ -106,7 +111,7 @@ public Entry(Integer time) { | |
private Gson g = new Gson(); | ||
HashMap<String, Integer> name_to_slot = new HashMap<String, Integer>(); | ||
HashMap<Integer, Integer> slot_to_playerslot = new HashMap<Integer, Integer>(); | ||
HashMap<Integer, Integer> cosmeticsMap = new HashMap<Integer, Integer>(); | ||
HashMap<Integer, Integer> cosmeticsMap = new HashMap<Integer, Integer>(); | ||
InputStream is = null; | ||
OutputStream os = null; | ||
|
||
|
@@ -120,7 +125,6 @@ public Parse(InputStream input, OutputStream output) throws IOException | |
System.err.format("total time taken: %s\n", (tMatch) / 1000.0); | ||
} | ||
|
||
|
||
public void output(Entry e) { | ||
try { | ||
this.os.write((g.toJson(e) + "\n").getBytes()); | ||
|
@@ -291,15 +295,11 @@ public void onCombatLogEntry(Context ctx, CombatLogEntry cle) { | |
} | ||
|
||
@OnEntityEntered | ||
public void onEntityEntered(Context ctx, Entity e) { | ||
processEntity(ctx, e, false); | ||
} | ||
|
||
@OnEntityLeft | ||
public void onEntityLeft(Context ctx, Entity e) { | ||
processEntity(ctx, e, true); | ||
public void onEntityExistenceChanged(Context ctx, Entity e) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since the annotation here is still OnEntityLeft, I think the method name should reflect that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, if this is only here for cosmetics entities, you should probably just keep the OnEntityEntered and remove OnEntityLeft (assuming ward-related annotated methods will be called separately) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah that could be a good way to catch this. |
||
processEntity(ctx, e); | ||
} | ||
|
||
@UsesEntities | ||
@OnTickStart | ||
public void onTickStart(Context ctx, boolean synthetic) { | ||
|
@@ -459,6 +459,19 @@ public void onTickStart(Context ctx, boolean synthetic) { | |
} | ||
} | ||
} | ||
|
||
@OnWardCountered | ||
public void onWardCountered(Context ctx, Entity e, String killer_hero_name) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. camelCase |
||
Entry wardEntry = buildWardEntry(ctx, e); | ||
wardEntry.attackername = killer_hero_name; | ||
output(wardEntry); | ||
} | ||
|
||
@OnWardExpired | ||
@OnWardPlaced | ||
public void onWardExistenceChanged(Context ctx, Entity e) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you unify this method with the previous one and detect from context which case it is? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think I can do that as the signatures are different. |
||
output(buildWardEntry(ctx, e)); | ||
} | ||
|
||
public <T> T getEntityProperty(Entity e, String property, Integer idx) { | ||
try { | ||
|
@@ -476,51 +489,44 @@ public <T> T getEntityProperty(Entity e, String property, Integer idx) { | |
} | ||
} | ||
|
||
public void processEntity(Context ctx, Entity e, boolean entityLeft) | ||
public void processEntity(Context ctx, Entity e) | ||
{ | ||
//CDOTA_NPC_Observer_Ward | ||
//CDOTA_NPC_Observer_Ward_TrueSight | ||
//s1 "DT_DOTA_NPC_Observer_Ward" | ||
//s1 "DT_DOTA_NPC_Observer_Ward_TrueSight" | ||
boolean isObserver = e.getDtClass().getDtName().equals("CDOTA_NPC_Observer_Ward"); | ||
boolean isSentry = e.getDtClass().getDtName().equals("CDOTA_NPC_Observer_Ward_TrueSight"); | ||
if (isObserver || isSentry) { | ||
//System.err.println(e); | ||
Entry entry = new Entry(time); | ||
Integer x = getEntityProperty(e, "CBodyComponent.m_cellX", null); | ||
Integer y = getEntityProperty(e, "CBodyComponent.m_cellY", null); | ||
Integer z = getEntityProperty(e, "CBodyComponent.m_cellZ", null); | ||
Integer[] pos = {x, y}; | ||
entry.x = x; | ||
entry.y = y; | ||
entry.z = z; | ||
if (entityLeft) | ||
if (e.getDtClass().getDtName().equals("CDOTAWearableItem")) { | ||
Integer accountId = getEntityProperty(e, "m_iAccountID", null); | ||
Integer itemDefinitionIndex = getEntityProperty(e, "m_iItemDefinitionIndex", null); | ||
//System.err.format("%s,%s\n", accountId, itemDefinitionIndex); | ||
if (accountId > 0) | ||
{ | ||
entry.type = isObserver ? "obs_left" : "sen_left"; | ||
cosmeticsMap.put(itemDefinitionIndex, accountId); | ||
} | ||
else | ||
{ | ||
entry.type = isObserver ? "obs" : "sen"; | ||
} | ||
entry.key = Arrays.toString(pos); | ||
entry.entityleft = entityLeft; | ||
entry.ehandle = e.getHandle(); | ||
//System.err.println(entry.key); | ||
Integer owner = getEntityProperty(e, "m_hOwnerEntity", null); | ||
Entity ownerEntity = ctx.getProcessor(Entities.class).getByHandle(owner); | ||
entry.slot = ownerEntity != null ? (Integer) getEntityProperty(ownerEntity, "m_iPlayerID", null) : null; | ||
//2/3 radiant/dire | ||
//entry.team = e.getProperty("m_iTeamNum"); | ||
output(entry); | ||
} | ||
else if (e.getDtClass().getDtName().equals("CDOTAWearableItem")) { | ||
Integer accountId = getEntityProperty(e, "m_iAccountID", null); | ||
Integer itemDefinitionIndex = getEntityProperty(e, "m_iItemDefinitionIndex", null); | ||
//System.err.format("%s,%s\n", accountId, itemDefinitionIndex); | ||
if (accountId > 0) | ||
{ | ||
cosmeticsMap.put(itemDefinitionIndex, accountId); | ||
} | ||
} | ||
} | ||
} | ||
|
||
Entry buildWardEntry(Context ctx, Entity e) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add method visibility |
||
Entry entry = new Entry(time); | ||
boolean isObserver = e.getDtClass().getDtName().equals("CDOTA_NPC_Observer_Ward"); | ||
Integer x = getEntityProperty(e, "CBodyComponent.m_cellX", null); | ||
Integer y = getEntityProperty(e, "CBodyComponent.m_cellY", null); | ||
Integer z = getEntityProperty(e, "CBodyComponent.m_cellZ", null); | ||
Integer life_state = getEntityProperty(e, "m_lifeState", null); | ||
Integer[] pos = {x, y}; | ||
entry.x = x; | ||
entry.y = y; | ||
entry.z = z; | ||
entry.type = isObserver ? "obs" : "sen"; | ||
entry.entityleft = life_state == 1; | ||
entry.key = Arrays.toString(pos); | ||
entry.ehandle = e.getHandle(); | ||
|
||
if (entry.entityleft) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use braces for all if statements |
||
entry.type += "_left"; | ||
|
||
//System.err.println(entry.key); | ||
Integer owner = getEntityProperty(e, "m_hOwnerEntity", null); | ||
Entity ownerEntity = ctx.getProcessor(Entities.class).getByHandle(owner); | ||
entry.slot = ownerEntity != null ? (Integer) getEntityProperty(ownerEntity, "m_iPlayerID", null) : null; | ||
//2/3 radiant/dire | ||
//entry.team = e.getProperty("m_iTeamNum"); | ||
return entry; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package yasp.processors.warding; | ||
|
||
import java.lang.annotation.Annotation; | ||
|
||
import skadistats.clarity.event.UsagePointMarker; | ||
import skadistats.clarity.event.UsagePointType; | ||
import skadistats.clarity.model.Entity; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target(value = ElementType.METHOD) | ||
@UsagePointMarker(value = UsagePointType.EVENT_LISTENER, parameterClasses = { Entity.class, String.class }) | ||
public @interface OnWardCountered { | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package yasp.processors.warding; | ||
|
||
import java.lang.annotation.Annotation; | ||
|
||
import skadistats.clarity.event.UsagePointMarker; | ||
import skadistats.clarity.event.UsagePointType; | ||
import skadistats.clarity.model.Entity; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target(value = ElementType.METHOD) | ||
@UsagePointMarker(value = UsagePointType.EVENT_LISTENER, parameterClasses = { Entity.class }) | ||
public @interface OnWardExpired { | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
preferably we should find a way to avoid needing to swap this dependency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I took like 3 hours today trying to make this work. Maybe @spheenik can give some guidance because the shaded jar will crash upon populating the processors. It seems it cannot find the annotations or whatever.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC this produces a jar with a different name. We have to make sure the output file is named the same, or update the Dockerfile to start the correct file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem here is that there is an annotation scanner in clarity (
org.atteo.classindex
) that scans annotations on compile time, and produces a fileMETA-INF/annotations/skadistats.clarity.event.Provides
which contains a list of all classes with Provides-annotations. If you use shade, you got to make sure this file is present and correctly merged.