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

Plugins #828

Closed
azeier opened this issue Mar 26, 2015 · 33 comments
Closed

Plugins #828

azeier opened this issue Mar 26, 2015 · 33 comments

Comments

@azeier
Copy link
Member

azeier commented Mar 26, 2015

I've been playing with the idea of adding plugin support for a while now and got around to testing it for a bit today. I like it.
Plugins would (at least for a start) just have access to everything and I will probably add an API later on.

Roughly the interface:

string Name { get; }
string Description { get; }
Version Version { get; }
void Load();
void OnButtonPress(); //settings button
void OnUpdate(); //called every 100ms

Is there interest in this?
Thoughts? Suggestions?

This is my first time trying to implement something like this. Anything specific I should pay attention to or be careful with?

@FenrisWolffe
Copy link

I don't know what plugins you would add, honestly. This software is wonderful as it is. The plugins would be things like "archive your decks" (already in), "notate your games" (Done.) "Import from websites" (Yep.)

I guess you were accidentally too efficient. :p

@azeier
Copy link
Member Author

azeier commented Mar 26, 2015

Well, plugins allow for others to add functionality without it having to be "built-in".
Meaning:
a) I don't need to maintain it :P
b) Plugins can be updated without updating the tracker itself (and partially vice-versa)
c) Plugins can add functionality I don't want to officially add to the software. Say.. you want to change your wallpaper, depening on the deck you are playing. Plugins could do that.

@Eldenroot
Copy link

it could bring more problems than advantages :( please focus on fixing bugs and adding features which were reported here :)

@azeier
Copy link
Member Author

azeier commented Mar 26, 2015

I do rarely do things other than fixing reported bugs and implementing suggested features.

Please note that this is a project I work on
a) in my spare time
b) for free
and most important: c) for fun!

Pluigins are fun because it is something new to learn and try out. Having fun means I am less likely to get burnt out and am more likely keep adding and fixing stuff (given I have the time to do so). Makes sense?

SO, you were speaking of problems. Please do elaborate.

@mkrain
Copy link

mkrain commented Mar 26, 2015

What sort of architecture do you have in mind for your plug-ins? Implementing a specific interface from an API and pulling in the plug-ins via an assembly load using reflection? Or will we have submit PR's for plug-in inclusion?

@azeier
Copy link
Member Author

azeier commented Mar 26, 2015

My current test setup is the former. PRs would kinda defeat the purpose :).
I just pushed it to a remote branch now: see here.

Obviously not done yet, probably lots of public/internal issues, but the basic functionality is there. Reference the exe, implement IPlugin, place dll in HDT/Plugins, good to go.

There are not really any events in the code plugins could hook on to at the moment either, might be something to consider. Probably the easiest by exposing an API for the most common things.

@BenReierson
Copy link

Seems like a good idea. I cloned the code yesterday and think it would be fun to try out a couple features.

I definitely think having some events to subscribe to would be needed. Let's say someone wanted to monitor active games and do some deck type detection, they'd want easy access to knowing the state of the game and when cards are played. Seems pretty straight-forward.

@azeier
Copy link
Member Author

azeier commented Mar 28, 2015

Not really sure how to handle events yet. Having "normal" public events means plugins could crash the whole app, no good. Just try-catching those means if the first throws an exception, no one else gets notified, no good either.

Maybe having multiple interfaces plugins could implement is the way to go?

IDeckManager:
-OnNewDeckCreated
-OnDeckSelected
...
IGameEvents:
-OnGameStart
-OnGameEnd
-OnPlayerDraw
...

Stuff like that?

@Eldenroot
Copy link

@Epix37 - I fully understand, I have coding like a hobby (I am a member of 3 free open source projects).

First of all, it would be really good if you can delete issues which are not relevant - I can fix some issues which are mentioned here on GitHub but I must to know what is a valid or invalid report. Also milestones and sort issues into categories would be nice. We have there over 165 issues, I think that almost 40% are out of date or not complete useless bug reports.

I really like your Deck Tracker and I am happy everytime when you release a new version with new features and bug fixes.

EDIT: What about these 4 PRs which are not merged? I really like the ideas, maybe you can add them in your way

@midnightviking
Copy link

I am currently building a web interface to check my own micro-statistics relating to the cards. Things like "How often did I get 2 doomguards in my hand? How many of those times did it happen before I could play even one? How often have I mulliganed into Tirion?" so I can make informed decisions on whether or not to cut duplicates of cards or think of better synergies.

I am doing it however using the 1300+ replays I have from your app! Its difficult to disseminate the replays but its coming along. Having the ability to make my own plugin for your app to easily export only relevant data from the HDT replays/logs would be great! So I fully support this idea!

azeier pushed a commit that referenced this issue Mar 30, 2015
@azeier
Copy link
Member Author

azeier commented Mar 30, 2015

@CU8ER I do clean up from time to time, but often when it comes to how to spend my time (coding vs cleaning here), coding wins. As for the PRs, I don't completely dislike the ideas, that's why they are still there. None of those are very high priority though. Feel free to keep pointing out outdated/solved issues and I will gladly close them.

Actually on topic:
I think I found a decent way of letting plugins have (save) access to events: the ones I added for a start. Currently there would be no way to unsubscribe from those events but I think chances are noone would do that anyway, ever, right? :) Also as of now, the events would keep getting called even if the plugin is disabled (at a later point). Need to figure out something for that... Figured out.

@andburn
Copy link
Member

andburn commented Mar 30, 2015

I think plugins are a great idea, it will really help you to concentrate on the core functionality. I've already got some ideas, have to go look at the code.

azeier pushed a commit that referenced this issue Mar 30, 2015
@azeier
Copy link
Member Author

azeier commented Mar 30, 2015

Added a few more events.

Here is a test build: https://github.com/Epix37/HDT-Test/releases/tag/v0.9.8_PRE3_PLUGINS

  1. reference HearthstoneDeckTracker.exe
  2. implement Plugins.IPlugin
  3. do whatever!
  4. place YourPlugin.dll in Hearthstone Deck Tracker/Plugins
  • plugins are displayed under options > plugins
  • "events": API.DeckManagerEvents and API.GameEvents

This is one where I really need feedback more than ever. What other events or API fuctionallity would you guys want? What's public but should be internal? Vice-versa?

@GiggliG
Copy link

GiggliG commented Mar 30, 2015

Would this allow a plugin writer to create a plugin which exports the data you see on the stats screen to another file, like a csv spreadsheet?

@azeier
Copy link
Member Author

azeier commented Mar 30, 2015

It would, yes.

@smikula
Copy link
Contributor

smikula commented Mar 30, 2015

Count me as a +1 for thinking plugins are a great idea. I've been toying with the idea of building a metagame tracking website, and it would be awesome if a HDT plugin could submit game results every time a game finishes.

I haven't had a chance to look at the HDT code much yet, but it sounds like you've already got most of what I'd need -- basically just an event every time a game ends and a way to get at the replay so I can see what cards got played.

The one other thing I can think of is some way to hook into the UI, like the way Hearthstats gets a dropdown off the main toolbar.

@azeier azeier added this to the v10.0 milestone Apr 1, 2015
@azeier
Copy link
Member Author

azeier commented Apr 1, 2015

Would a "Plugins" menu item (or even titlebar dropdown button) be sufficient? I could then give IPlugin a bool WantMenuEntry and MenuItem MenuEntry.

Being able to add entries to the main menu would technically not be an issue either but the menubar does not really handle too many items to well. If an item cant be fully displayed it just gets cut off.

@andburn
Copy link
Member

andburn commented Apr 1, 2015

I've been trying out the plugin interface with a quick implementation of @GiggliG stats to csv idea. It all seems to work great. I can't think of any other events at the moment, you seem to have the relevant ones covered. As regards public vs internal nothing jumps out at me yet, but I didn't really look that close 😄

I do like the menu item or toolbar idea. The plugins menu item sounds best, otherwise the menu bar will get out of hand. It will make the plugins functionality more accessible too.

@GiggliG
Copy link

GiggliG commented Apr 1, 2015

That sounds great, andburn. Would you be able to choose between deck, class, or all stats for export? (Not that it really matters, you could filter after export if you grab everything).

Epix, would a plugin be able to alter the layout of current forms?
Here for instance here are a few features I'd like to see, and I wonder if plugins could make them?

  • Add an extra line of detail to the Deck Stats page, that showed the frequency each enemy class was encountered within the current filter time period (not just by this deck, by all decks)?
  • Add new filters to the deck stats (like server), replace existing filters (like change the Mode to a multi-select format, so you could pick Ranked + Casual, or change Timeframe to a date picker with Start and End times).
  • Edit stats en masse, so i could select all games with a particular deck, and change the server to US or EU, for instance.
  • add a text box at the top of the deck list, so that I could enter letters and it would filter to show only decks with those letters in the name
  • at the top of the deck list we have Arena, Constructed, and down the side the 9 classes plus archive. In one of those places I'd like to add specific tags (like "Favourite") so i could click and it would filter to decks with that tag, but also when i click one of the other buttons it would clear that filter (to avoid the menu fiddling).

@azeier
Copy link
Member Author

azeier commented Apr 1, 2015

As it stands, changing the UI is probably possible but very "hacky" and will probably easily break if things in the UI change.

Add an extra line of detail to the Deck Stats page, that showed the frequency each enemy class was encountered within the current filter time period (not just by this deck, by all decks)?

Possibly, not sure. That's something I would very much willing to have by default though, so a pullrequest would be a much better fit for this.

Add new filters to the deck stats (like server), replace existing filters (like change the Mode to a multi-select format, so you could pick Ranked + Casual, or change Timeframe to a date picker with Start and End times).

Probably not? Maybe. Again, I would have no problems with this as a default.

Edit stats en masse, so i could select all games with a particular deck, and change the server to US or EU, for instance.

Yes. But again, no need for that to be a plugin.

add a text box at the top of the deck list, so that I could enter letters and it would filter to show only decks with those letters in the name

Maybe :). If it's implemented and integrated in a fitting way I would not mind having this as a default feature either.

at the top of the deck list we have Arena, Constructed, and down the side the 9 classes plus archive. In one of those places I'd like to add specific tags (like "Favourite") so i could click and it would filter to decks with that tag, but also when i click one of the other buttons it would clear that filter (to avoid the menu fiddling).

Again maybe. And again something that I wouldn't really mind as a default feature.

In conclusion: Just because things can (or could) be done as plugins does not mean that's it's necessary, the best way or even the easiest way. All of the things above would be way easier to implement directly in the application, than into make them work as plugins.

@GiggliG
Copy link

GiggliG commented Apr 1, 2015

If those features can be added as core features, fantastic! I just didn't want to give you extra work.

@azeier
Copy link
Member Author

azeier commented Apr 2, 2015

@GiggliG Well, it's not neccessarily me doing the work :). But whoever would implement those as plugins might as well just submit a pullrequest for the feature. That's the point I was trying to make.

Another topic:
Not sure if this will be actually useful for anyone but me, but the next pre/release (not 0.9.10) will have a simple debug window, which currently displays (live) all property of the Game class and all entites during a game. Accessible via options > tracker > logging > debugwindow.

If you are planning on making plugins it's probably at least interesting.

http://imgur.com/a/8Gf4I

@andburn
Copy link
Member

andburn commented Apr 2, 2015

The debug window could be very useful, great feature.

@FenrisWolffe
Copy link

FenrisWolffe commented Apr 3, 2015 via email

@azeier
Copy link
Member Author

azeier commented Apr 5, 2015

Plugins will be in the next update! So if anyone wanted to create plugins but wanted to hold off until it's actually in the software, it is now :). There will probably still be lots of modifications but (I think) nothing that should horribly break your code.

V0.10.0 prerelease: https://github.com/Epix37/HDT-Test/releases/tag/v0.10_PRE1

I will be adding your (open souce) plugins to a list in the main readme (or wiki?), unless you don't want me to obviously. The tracker's "available plugins" link will refer to that, at least for the moment.

Small wikl entry on plugin creation: https://github.com/Epix37/Hearthstone-Deck-Tracker/wiki/Creating-Plugins

@FenrisWolffe
Copy link

Extracted the release into the directory, and all hell broke loose. Prepare for wall of text:

please use pastebin http://pastebin.com/D5saSy4p

@azeier
Copy link
Member Author

azeier commented Apr 5, 2015

fixed and uploaded new build

@andburn
Copy link
Member

andburn commented Apr 11, 2015

The plugin functionality is looking good. I have a couple of requests/suggestions:

  • Could you add a wrapper method in Helper for User32.GetHearthstoneRect(), so it can be accessed from a plugin. It would make using Helper.CaptureHearthstone() easier, and avoid some duplication.
  • Also, is it possible for the plugin code to check sub-directories of the /Plugins directory? The plugins could exist in their own directories, enabling them to have some configs or other libraries without interfering with others. (Unless there is a way of packing all the needed stuff into the one dll?).

@jonathansharman
Copy link

This is great! Thanks for doing this. Quick question: what's the most sensible way to added UI elements to the in-game overlay?

@azeier
Copy link
Member Author

azeier commented May 7, 2015

At the moment there is no "out of the box" way to do this. You can probably make it work using reflection.

Would exposing the overlay canvas element already be enough?

Edit: Actually, that already is accessible. Helper.MainWindow.Overlay.CanvasInfo (not sure why it's called CanvasInfo...)

@jonathansharman
Copy link

I'm not super familiar with WPF, but I imagine that would work for what I want to do. :) I'd like to try adding fatigue counters.

@azeier
Copy link
Member Author

azeier commented May 7, 2015

FYI: fatigue counters already exist :). See options > overlay > player/opponent. They should show up before the first fatigue draw.

@jonathansharman
Copy link

Oh nice! I actually hadn't noticed. I more just wanted to experiment with the plugins anyway. Thank you!

@azeier azeier closed this as completed Jun 5, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

10 participants