forum

Osu!API++

posted
Total Posts
25
Topic Starter
abraker
Hi all! As I'm working on the player skill analyzer, I came up with a C++ API that would allow me to interface with the Osu! API in a good way and figured why not share it. There are somethings that are still unsupported and I will implement those things eventually. In the mean time, enjoy Osu API++, and I would love to hear some feedback.

Head over here!
DeathAlchemy
This seems like a good idea. :)

You could add:
Heat maps from plays
How close you are to hitting the middles of the hit circles over the time of the map with a graph
How close you are to hitting the circles on time over the time of the map with a graph
Tips for players to help them with speeding up their playing, streams, and jumps
Recording stats while playing with ranks and such

This is a good idea, i would like to use it if there could be some stats info to look at and also tips to help on peoples playing styles.
Topic Starter
abraker

DeathAlchemy wrote:

Heat maps from plays
How close you are to hitting the middles of the hit circles over the time of the map with a graph
How close you are to hitting the circles on time over the time of the map with a graph
Tips for players to help them with speeding up their playing, streams, and jumps
Recording stats while playing with ranks and such
Woah, woah, woah! This is just a C++ equivelant to osu! API, not its own thing. To do what you have mentioned would require reading the replay file and not this. I suggest you go here to see what this API can and cannot do. Apart from that, I will definitely consider making an API to read replay files in the near future.
DeathAlchemy

abraker wrote:

DeathAlchemy wrote:

Heat maps from plays
How close you are to hitting the middles of the hit circles over the time of the map with a graph
How close you are to hitting the circles on time over the time of the map with a graph
Tips for players to help them with speeding up their playing, streams, and jumps
Woah, woah, woah! This is just a C++ equivelant to osu! API, not its own thing. To do what you have mentioned would require reading the replay file and not this. I suggest you go hereto see what this API can and cannot do. Apart from that, I will definitely consider making an API to read replay files in the near future.
Sorry i got really excited :oops:

also while trying to build the application this happened...http://imgur.com/sbEvLxU
Bauxe

DeathAlchemy wrote:

Sorry i got really excited :oops:

also while trying to build the application this happened...http://imgur.com/sbEvLxU
I don't think you really understand what this is for.

However the issue there seems to be the path to JSON_Parser.cpp is incorrect.
Topic Starter
abraker
Make sure you have these set correctly, referencing where the files are. Also this IS NOT an application, it's a library.
DeathAlchemy

Bauxe wrote:

DeathAlchemy wrote:

Sorry i got really excited :oops:

also while trying to build the application this happened...http://imgur.com/sbEvLxU
I don't think you really understand what this is for.

However the issue there seems to be the path to JSON_Parser.cpp is incorrect.
You are correct as i said before i didn't read the post all the way through, as i got excited and wrote what i did.

abraker wrote:

Make sure you have these set correctly, referencing where the files are. Also this IS NOT an application, it's a library.
http://imgur.com/gIWLZuk
Topic Starter
abraker
Pull the new update. I separated the headers and sources into their own folders.
DeathAlchemy

abraker wrote:

Pull the new update. I separated the headers and sources into their own folders.
built went well but now a lib file is missing.
http://imgur.com/WaTyCQQ
Topic Starter
abraker

abraker wrote:

this IS NOT an application, it's a library.
Change the target.

Soinou
Not a bad idea, but here are some remarks:

  1. The usage seems awfully hard for what it does, I mean instead of registering the parameters as params[whatever], then call the get method, why not just call the get methods with the parameters ?
  2. Your project file is called Project4, you should probably rename it (You can juste rename it then reopen it, everything will work. Maybe you'll have to delete and reimport the vcxproj file, but well ...)
  3. Oh, and you have something agains conventions it seems. You have JSON_Parser, OsuInfo, download as filenames. You can't have three name conventions for three files, that's just wrong.
  4. Instead of using static methods on a class, consider making this class a singleton.
  5. If you want to use constants that are 0/1/2/3, instead of putting them in a namespace and making them strings, just use an enumeration, they will be considered as integers. Or just pass the game mode as a third arguments and use defines, it will be the same and probably faster since you will in the end pass numbers directly.
  6. You should use a JSON library instead of creating your own or copying it from somewhere else. Use something like JsonCpp or any other library of the kind. They're easy to use, have a lot of useful functionalities and make your code simpler. Libraries are made to be reused, you should use them. Don't recode something that is already coded.
  7. You are returning weird arrays from your functions. Why not make a custom type, like an OsuUser or an OsuBeatmap and return it ? Seems a lot easier to code and use.
Well, those are just remarks, you can do whatever you want with them. I'm not a pro, so feel free to just ignore me :D.
Topic Starter
abraker

Soinou wrote:

The usage seems awfully hard for what it does, I mean instead of registering the parameters as params[whatever], then call the get method, why not just call the get methods with the parameters ?
I might not fully understood what you meant, but I did it this way to make the coding cleaner. If I did
 Osu_Info::getInfo(Osu_Info::MODE::get_user_best, "param1", "param2", "param3", etc);
Then the order of the parameters would matter and in most cases not all paramaters will be used. Consider this code:
// load parameters
params[U32 Osu_Info::PARAM::user_ID] = "abraker";
params[U32 Osu_Info::PARAM::game_mode] = GAMEMODE::Mania;
params[U32 Osu_Info::PARAM::limit] = "50";
user_best = Osu_Info::getInfo(Osu_Info::MODE::get_user_best, params);
If I was to do what you propose it would look like this:
Osu_Info::getInfo(Osu_Info::MODE::get_user_best,  "abraker", "", "50", "", "", "",  GAMEMODE::Mania, "");
I suppose I can do this, but it looks ugly IMO.

Soinou wrote:

Your project file is called Project4, you should probably rename it (You can juste rename it then reopen it, everything will work. Maybe you'll have to delete and reimport the vcxproj file, but well ...)
I can't figure this out for the life of me! There doesn't seem an easy to do this within Visual Studio. I think I will have to create a new project and copy everything to the new folder. I'll do this in the next update.

Soinou wrote:

Oh, and you have something agains conventions it seems. You have JSON_Parser, OsuInfo, download as filenames. You can't have three name conventions for three files, that's just wrong.
XD well that slipped out of my coding standards some how. Nice Catch! Will fix in the next update, and yes it's just wrong.

Soinou wrote:

Instead of using static methods on a class, consider making this class a singleton.
Will do.

Soinou wrote:

If you want to use constants that are 0/1/2/3, instead of putting them in a namespace and making them strings, just use an enumeration, they will be considered as integers. Or just pass the game mode as a third arguments and use defines, it will be the same and probably faster since you will in the end pass numbers directly.
Do I? I am using it as a string.
if (_param[U32 PARAM::game_mode] != "")
url += ("m=" + _param[U32 PARAM::game_mode] + "&");
I could pass it as a 3rd parameter, but I want to keep consistency. All parameters will be passed through an array of 8 strings.

Soinou wrote:

You should use a JSON library instead of creating your own or copying it from somewhere else. Use something like JsonCpp or any other library of the kind. They're easy to use, have a lot of useful functionalities and make your code simpler. Libraries are made to be reused, you should use them. Don't recode something that is already coded.
I agree and was thinking of doing so. Perhaps it's my laziness of bothering of including other libraries that lead to this. I might consider doing this after the next update.

Soinou wrote:

You are returning weird arrays from your functions. Why not make a custom type, like an OsuUser or an OsuBeatmap and return it ? Seems a lot easier to code and use.
You mean typedef? If so, I did it for the previous design with tables, but didn't feel like vector<vector<string>> needed one. Though, I can make it so.

  • *updated the git with todo's. Will start working on fixing/adding the features this weekend or next week.
Topic Starter
abraker
Alright I
  • - Renamed the project4 folder to Osu!API++
    - Made filenames follow one naming convention
    - And Made the static classes singletons
In the next update expect the current JSON code to be replaced by a JASON library. Also unfortunately when overwriting the master branch, I lost the readme text file which had the info on how to use the Osu!API++ library, so I'll have fun rewriting that too. The tutorial.cpp file should still be there (renamed it from main.cpp to tutorial.cpp).
Nabile

abraker wrote:

  • - And Made the static classes singletons
You might want to read this about singletons.
Topic Starter
abraker

Nabile wrote:

abraker wrote:

  • - And Made the static classes singletons
You might want to read this about singletons.
I realized I didn't use the instance variable declared in the singleton classes and is fixed now. Other than that, I am not sure if you pointed me there due to design or incorrect implementation, so I'll address both. Honestly I am split between the static design and singleton design. If you think my implementation of a singleton is wrong, mind pointing out where and/or how?
Nabile

abraker wrote:

I realized I didn't use the instance variable declared in the singleton classes and is fixed now. Other than that, I am not sure if you pointed me there due to design or incorrect implementation, so I'll address both. Honestly I am split between the static design and singleton design. If you think my implementation of a singleton is wrong, mind pointing out where and/or how?
Singletons are a solution in the short term. As explained in the chapter, they are going to be a pain in the long term (for reasons described in Why we regret using it).
Depending on what you were trying to solve, you could choose a different approach, like letting the user of this library instantiate the API and ensuring it has only one instance, and passing the reference when required instead of having a global variable. Or see if you need an instance at all, if not a simple static class will do. Not only that but it'll be better to write Foo::bar() instead of Foo::getInstance().bar() everywhere.

But that's only an advice :p
Topic Starter
abraker

Soinou wrote:

Instead of using static methods on a class, consider making this class a singleton.
Since I am split between the two, I followed Soinou's advice. Unless those classes will be extended and the code becomes more complex, I don't think it matters which design I use.
Bobbias

abraker wrote:

Unless those classes will be extended and the code becomes more complex, I don't think it matters which design I use.
Actually, it totally does matter. Singletons are much harder for anyone to extend. Programming is one of the few places where considering how things might change in the future can be extremely helpful. Singletons are extremely difficult to refactor compared to other approaches, among other issues.

I feel dirty just looking at code with a lot of static/global values. That would be the reason I never refactored wanwan159's o2jam to osu converter.
Topic Starter
abraker

Bobbias wrote:

stuff
I am probably seeing this in the perspective where I can't imagine why you would want to extend the classes in this library. Just in case that I'm missing something, there is the static approach and singleton approach. Is there a better approach to this? The original idea was to make everything static so that the code would be clean while forcing there to be only one copy of the class.
theLiminator
Oftentimes inheritance is a code smell anyways. Though singletons kinda are too.
show more
Please sign in to reply.

New reply