Skip to content
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

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
82 changes: 55 additions & 27 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,27 +40,27 @@
</repository>
</repositories>
<dependencies>
<!--
<dependency>
<groupId>com.github.skadistats</groupId>
<artifactId>clarity</artifactId>
<version>master-SNAPSHOT</version>
</dependency>
-->
<!--
<dependency>
<groupId>com.github.skadistats</groupId>
<artifactId>clarity</artifactId>
<version>70956f5a89fca56f3a292e739ea3eda96a33fd8c</version>
</dependency>
-->
<!--
<dependency>
<groupId>com.github.skadistats</groupId>
<artifactId>clarity</artifactId>
<version>master-SNAPSHOT</version>
</dependency>
-->
<!--
<dependency>
<groupId>com.github.skadistats</groupId>
<artifactId>clarity</artifactId>
<version>70956f5a89fca56f3a292e739ea3eda96a33fd8c</version>
</dependency>
-->

<dependency>
<groupId>com.skadistats</groupId>
<artifactId>clarity</artifactId>
<version>2.1</version>
</dependency>

<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
Expand All @@ -71,24 +71,52 @@
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.2</version>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>yasp.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<!-- this is used by clarity-example and clarity-analyzer -->
<plugin>
<groupId>com.jolira</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.4.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
<goal>one-jar</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>yasp.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
<!-- for some reason the shade-plugin doesn't work well with clarity processors.
Copy link
Member

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.

Copy link
Author

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.

Copy link
Member

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.

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 file META-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.

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>yasp.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
-->
</plugins>
</build>
</project>
58 changes: 39 additions & 19 deletions src/main/java/yasp/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,55 @@

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) 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();
if (args.length > 0 && args[0].equals("--file")) { System.exit(parseFile(args[1])); }
else if (args.length > 0 && args[0].equals("--")) { System.exit(parseStream(System.in, System.out)); }
else { startServer(args); }
}

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();
}

private static int parseStream(InputStream is, OutputStream os) throws IOException {
try {
new Parse(is, os);
}
catch (Exception e)
{
e.printStackTrace();
return -1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra space

}
finally {
is.close();
os.close();
}

return 0;
}

private static int parseFile(String replayFile) throws Exception {
System.out.print(String.format("Parsing file %s", replayFile));
return parseStream(new FileInputStream(replayFile), 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());
}
}
}
108 changes: 57 additions & 51 deletions src/main/java/yasp/Parse.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.OnWardExpired;
import yasp.processors.warding.OnWardPlaced;
import yasp.processors.warding.OnWardKilled;

public class Parse {
private class Entry {
Expand Down Expand Up @@ -96,6 +100,7 @@ public Entry(Integer time) {
this.time = time;
}
}

float INTERVAL = 1;
float nextInterval = 0;
Integer time = 0;
Expand All @@ -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;

Expand All @@ -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());
Expand Down Expand Up @@ -292,14 +296,9 @@ 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);
processEntity(ctx, e);
}

@UsesEntities
@OnTickStart
public void onTickStart(Context ctx, boolean synthetic) {
Expand Down Expand Up @@ -459,6 +458,19 @@ public void onTickStart(Context ctx, boolean synthetic) {
}
}
}

@OnWardKilled
public void onWardKilled(Context ctx, Entity e, String killerHeroName) {
Entry wardEntry = buildWardEntry(ctx, e);
wardEntry.attackername = killerHeroName;
output(wardEntry);
}

@OnWardExpired
@OnWardPlaced
public void onWardExistenceChanged(Context ctx, Entity e) {
Copy link
Member

Choose a reason for hiding this comment

The 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?

Copy link
Author

Choose a reason for hiding this comment

The 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 {
Expand All @@ -476,51 +488,45 @@ 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);
}
}
}

private Entry buildWardEntry(Context ctx, Entity e) {
Entry entry = new Entry(time);
boolean isObserver = !e.getDtClass().getDtName().contains("TrueSight");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra space

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) {
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;
}
}
19 changes: 19 additions & 0 deletions src/main/java/yasp/processors/warding/OnWardExpired.java
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 {
}

19 changes: 19 additions & 0 deletions src/main/java/yasp/processors/warding/OnWardKilled.java
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 OnWardKilled {
}

Loading