Giter VIP home page Giter VIP logo

modio-sdk-legacy's Introduction

NOTE: This codebase is now deprecated.

The latest version of the mod.io Unreal Plugin can be found at https://github.com/modio/modio-sdk.

mod.io

Legacy mod.io SDK

License Discord Master docs GitHub Action

Welcome to the legacy mod.io SDK repository, built using C and C++. This SDK allows game developers to host and automatically install user-created mods in their games. It connects to the mod.io API, and documentation for its functions can be viewed here.

Features

Feature Supported
Windows / Linux / MacOS
Standalone
Open Source
Free
Async Callbacks
Events
Prebuilt download and upload queue
Automatic downloads and updates
Email / Steam / GOG authentication
Browse / search / tag mods
Mod dependencies / comments / stats
Multilanguage C interface
MIT license

Usage

Browse mods

modio::FilterCreator filter_creator;
filter_creator.setLimit(5); // limit the number of results
filter_creator.setOffset(0); // paginate through the results by using a limit and offset together
filter_creator.setSort("date_updated", false); // the filtering system allows flexible queries

modio_instance.getAllMods(filter_creator, [&](const modio::Response& response, const std::vector<modio::Mod> & mods)
{
  if(response.code == 200)
  {
    // Mod data retrieved!
  }
});

Auth (via email)

Authentication enables automatic installs and updates under the hood.

First step is to request a security code to your email.

modio_instance.emailRequest("[email protected]", [&](const modio::Response& response)
{
  if (response.code == 200)
  {
    // Authentication code successfully sent to the e-mail
  }
});

Finish authentication by submitting the 5-digit code.

modio_instance.emailExchange("50AD4", [&](const modio::Response& response)
{
  if (response.code == 200)
  {
    // Email exchanged successfully, you are now authenticated
  }
});

External Auth

If your game is running inside a popular distribution platform such as Steam or GOG Galaxy you can authenticate 100% seamlessly.

Galaxy Auth

modio_instance.galaxyAuth(appdata, terms_agreed, [&](const modio::Response &response)
{
  if (response.code == 200)
  {
    // Successful Galaxy authentication
  }
});

Oculus Auth

modio_instance.oculusAuth(nonce, oculus_user_id, access_token, email, date_expires, terms_agreed, [&](const modio::Response &response)
{
  if (response.code == 200)
  {
    // Successful Oculus authentication
  }
});

Steam Auth

modio_instance.steamAuth(rgubTicket, cubTicket, terms_agreed, [&](const modio::Response &response)
{
  if (response.code == 200)
  {
    // Successful Steam authentication
  }
});

Subscriptions

Download mods automatically by subscribing, uninstall them by unsubscribing.

Subscribe

modio_instance.subscribeToMod(mod_id, [&](const modio::Response& response, const modio::Mod& mod)
{
  if(response.code == 201)
  {
    // Subscribed to mod successfully, the mod will be added automatically to the download queue
  }
});

Unsubscribe

modio_instance.unsubscribeFromMod(mod_id, [&](const modio::Response& response)
{
  if(response.code == 204)
  {
    // Unsubscribed from mod successfully, it will be uninstalled from local storage
  }
});

Mod ratings

modio_instance.addModRating(mod_id, 1 /*or -1 for negative rating*/, [&](const modio::Response& response)
{
  if(response.code == 201)
  {
    // Mod rating submitted successfully
  }
});

Mod submission

Share mods by creating a mod profile and attaching modfiles to it.

Create a mod profile

modio::ModCreator mod_creator;
mod_creator.setName("Graphics Overhaul Mod");
mod_creator.setLogoPath("path/to/image.jpg");
mod_creator.setHomepage("http://www.garphicsoverhaulmod.com");
mod_creator.setSummary("Short descriptive summary here.");
mod_creator.addTag("Graphics");
mod_creator.addTag("HD");

modio_instance.addMod(mod_creator, [&](const modio::Response& response, const modio::Mod& mod)
{
  if(response.code == 201)
  {
    // Mod profile successfully added
  }
});

Upload a modfile

modio::ModfileCreator modfile_creator;
modfile_creator.setModfilePath("path/to/mod_folder/");
modfile_creator.setModfileVersion("v1.1.0");
modfile_creator.setModfileChangelog("<p>Rogue Knights v1.2.0 Changelog</p></p>New Featu...");

modio_instance.addModfile(requested_mod.id, modfile_creator);

Listeners

Download listener

modio_instance.setDownloadListener([&](u32 response_code, u32 mod_id) {
  if (response_code == 200)
  {
    // Mod successfully downloaded. Call the modio_instance.installDownloadedMods(); to install, keep in mind this is not an async function.
  }
});

Upload listener

modio_instance.setUploadListener([&](u32 response_code, u32 mod_id) {
  if (response_code == 201)
  {
    //Mod successfully uploaded
  }
});

Feature rich integration

Visit the wiki to learn how to integrate dependencies, comments, stats, reports and more.

Getting started

If you are a game developer, first step is to add mod support to your game. Once mod support is up and running, create your games profile on mod.io, to get an API key and access to all functionality mod.io offers. Next, download the latest SDK release and unpack it into your project, then head over to the GitHub Wiki and follow the guides corresponding to your setup.

#include "modio.h"

// ...

modio::Instance modio_instance(MODIO_ENVIRONMENT_TEST, MY_GAME_ID, "MY API KEY");

// ...

void myGameTick()
{
  modio_instance.process();
}

Contributions Welcome

Our SDK is public and open source. Game developers are welcome to utilize it directly, to add support for mods in their games, or fork it to create plugins and wrappers for other engines and codebases. Many of these contributions are shared here. Want to make changes to our SDK? Submit a pull request with your recommended changes to be reviewed.

Wrappers

mod.io SDK wrappers are available for the following languages and engines:

Are you creating a wrapper? Let us know!

Building instructions

Learn how to build mod.io SDK in our building instruction guide.

Code contributions

  1. Fork it
  2. Add new features
git checkout -b my-new-feature
git commit -am 'Add some feature'
git push origin my-new-feature
  1. Create a pull request

Reporting a bug

If you're unable to find an open issue addressing the problem, open a new one. Be sure to include a title and clear description, as much relevant information as possible, and a code sample or an executable test case demonstrating the expected behavior that is not occurring.

Other Repositories

Our aim with mod.io, is to provide an open modding API. You are welcome to view, fork and contribute to our other codebases in use.

modio-sdk-legacy's People

Contributors

intenscia avatar ivantorres16 avatar markusrannare avatar melodatron avatar modio-jackson avatar morghan avatar morlad avatar nickelc avatar supsuper avatar turupawn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

modio-sdk-legacy's Issues

File responses should have a filehash object instead of a string.

The current API (v1) hard-codes MD5 as the file hash. MD5 should be considered broken as collision attacks are relatively easy to do and do not take long.

To make the API easier to update/extend in the future (without even bumping the API version) having filehash be an object would be a lot nicer.

filehash: {
  md5: "abcd",
  sha256: "1234",
  sha3-512: "5689"
}

By just providing multiple hashes adding better hashes is easily doable, without breaking users of the API, and allowing nice updates. In case some hash is severely broken in the future one could even just drop that one from a new version of the API.

Provide better hashes for modfiles

Currently the only checksum available for files is md5.

It would be nice if there's a checksum available that wasn't considered broken in the last century.

SHA-3 would be nice.

Filtering documentation needs some clarification and a running example

What does It is important to understand that when using filters in your request, the filters you specify will only be applied to the bottom-level columns. actually mean?

What is the bottom-level, what are columns? Are you talking about the top level entries in the JSON object (unlikely, at least given my tests, though that might just be broken)? Are you talking about the most deeply nested entries in that JSON, and if yes, what if there are multiple entries (with different paths) at the same depth?

It would be nice to be able to specify exactly what one wants to filter. So something like ?name=data.*.id:1234, so one can do more specific filtering.

At the very least some actual test data and examples and responses for those in the documentation would help.

Allow filtering based on modfile.filename.

Since we will only support showing/downloading mods with a certain extension (due to being portable, somewhat similar to .umod for those that spent too much time with UT; actually just zip files that contain a mod.json file with some data we use, and the files for the mod), it would be nice to do that filtering when submitting the query.

It should be working (unless I'm missing something in the documentation), but the below example does not seem to do what it should.

curl --request GET 'https://api.mod.io/v1/games/57/mods?api_key=use_your_own&filename-lk=*.zip'
curl --request GET 'https://api.mod.io/v1/games/57/mods?api_key=use_your_own&filename-lk=*.zio'

Both return the same results (5, that is), while I would expect the second one to not return any result, as the only files present are some demo.zip files (which also does not seem to have the same md5sum as the filehash would indicate).

Allow requesting just a certain set of fields for a query.

It would be nice if one could specify what parts of the "full" response one actually wants and thus not needing to transfer data that will not be used at all.

Currently we do a query curl --request GET 'https://api.mod.io/v1/games?api_key=use_your_own&nameid=0ad' and the only thing we actually care about in the response is "id": 57.

There are similar things for the other query curl --request GET 'https://api.mod.io/v1/games/57/mods?api_key=acf8fc07e3a8e9228ef4d5704c1659a1' (not the actual code, but equivalent, and easier to test), where we currently only need "name", "nameid", "summary", and "modfile": {"version", "filename", "filehash", "filesize", "download"} for each entry. All the other data is not really needed and it would be nicer if we could specify that when doing the query.

Depending on the infrastructure used this might also remove some ultimately unneccessary work the server has to do.

C++ headers have unnecessary includes

Currently all the #includes for the source code are in the header files, which avoids repetition, but pollutes any users of the SDK with unnecessary dependencies and system headers, since there's no way to access the library API without the headers. Clean headers make it easier to integrate with third-party code and avoid unnecessary conflicts.

  • Given how C++ works, it's better to keep includes as close to the source as possible and avoid them in the header files, even if it causes repetition, since library headers can be included anywhere and pull everything along with them.
  • The source files (.cpp) should carry most of the includes, as they're the ones calling functions. Header files (.h) only need to include other headers for types and defines they reference.
  • The include/ folder should only contain header files with the library's public API (functions and classes exported by the DLL), all the others should stay in the src/ folder. The ModioC.h is a good example, as it defines nothing but the public API.

Tools like https://include-what-you-use.org/ can help automate this process.

File responses should allow signed files

(Since in parts this API is trying to provide similar things as some package managers, learning some lessons from those is a good thing to do.)

It would be nice if one could optionally sign (most likely GPG (at least that is what most *nix package managers or related tools use, I'll still point towards OpenBSDs signify to indicate that there are alternatives)) mod files, so users of the API could verify that the files are actually the same as the mod creator provided. This removes some need to trust the actual API endpoint too much.

Error response improvement when submitting an existing nameid

When creating a mod using the Add Mod endpoint. If the optional param nameid is sent with an already existing value in mod.io, the server returns:

{"error":{"code":500,"message":"We experienced a server error attempting to complete your request. The issue has been logged and will be investigated, please try again later."}}

I think would be better if it returns 422 Unprocessable Entity with a message that explains that the mod could not be created because the nameid should be unique.

Documentation missing/incorrect entries

Missing:

  • Mod.logo, .url, and .media
  • Member
    Incorrect:
  • Mod.member and .modfile listed as integer (instead of data structure)
  • Modfile.member listed as integer (instead of data structure)

modioInit should return error on failure

Currently if there's an error in modioInit due to an invalid parameter (eg. invalid root path, no write permissions, etc) the SDK just fails silently since nothing is logged and any web requests will just respond normally.

  • Check for errors in modioInit and return true/false appropriately (will need an explicit ::init for C++)
  • If the logger failed, log errors to stderr instead.

/games/{game-id}/mods needs details on status for non-OAuth2 queries

If I query for mods without OAuth2, are the results only those with status "auth" (as it is listed as the default)?

It would be nice if one could ask for "auth" and "unauth" (so "auth+unauth" but not any of "ban", "archive", or "delete") without using OAuth2. I'd like to provide users access to mods that have been checked by developers (possibly by default, after notifying users that they will connect to the internet and whatnot), but I'd rather not list every mod there for security reasons.

(Our mods include scripts, which might be malicious, and I'd rather not expose users to such mods without a big warning telling them that they might be putting their machine at risk. So only listing mods checked by some of our developers would be the right thing to do. There aren't a whole lot of scripts in most mods we've seen so far, and if there are more than that they most likely have been written by someone on the team.)

Also how does the process of marking a mod as "authorized" work, the only 3 occurances of "authorized" in the documetation are twice in the status description, and once for a 401 response code.

Missing stars field from the docuemntation. Also, the descriptions have inconsistent caps

API example containing the stars fields:
https://api.mod.io/v1/games/7/mods?api_key=aea55da460bd50aa338f2b3da7e81f1f&_limit=1

The stars field is not present in the documentation
https://docs.mod.io/#rating-object
missingrating

Also, "Rating" on the descriptions has inconsistent caps. I think they should be all lowercase. The same applies to the nested Rating object on the mod documentation:
https://docs.mod.io/#mod-object

File response download links could follow some stable naming scheme.

The file paths returned are ugly in that one has to do tons of API requests instead of just being able to increment e.g. a version number and calling it done. This does not mean that there cannot be an API key in the URL allowing rate-limiting based on API keys.

This could be somewhat important for downstream projects that are packaged for some *nix systems, which would like to also package some mods and ship them. Would help a little with reducing the bandwidth and allow fully offline installation of mods.

Allow doing a query for all mods of a game in one query without knowing the game id.

(In my current WIP patch for 0 A.D. there need to be two queries before all the neccessary data is retrieved, because I don't hard-code the game id (to allow for different API endpoints, and to not force possible future users of the engine to use the same).

Currently the code does something roughly equivalent (to the following commands)

curl --request GET 'https://api.mod.io/v1/games?api_key=use_your_own&nameid=0ad'
# parse {"data":[{"id":57," ...
curl --request GET 'https://api.mod.io/v1/games/57/mods?api_key=use_your_own'

. It would be a lot nicer (and reduce the number of queries, even though the code will cache the game id after the first query (at least after some more integration work)) to be able to do a single request and get the result for the second query.

Also why does the first query even return an array of data if ids are unique, so there can only be 1 or 0 returned entries?

Option to not extract ZIPs on mod installation

Some games have built-in ZIP loading so mods don't need to be extracted to disk. Skipping this step makes the installation process much faster as it becomes a simple "move" operation and also requires less hard disk space.

Allow adding a small amount of (optional) metadata for modfiles

We internally use some JSON data to handle mods and their compatibility. Parts of it are also provided in the mod/modfile data returned currently, however a few custom fields (best encapsulated in some "custom" object) that can be set when uploading a mod (or at a later point using some tool) would help a lot.

Mainly we wouldn't allow the user to download mods that are not compatible with the current version of the game. We could also easily show that there is a compatible update of the mod available, or if that requires a newer version of the game indicate that.

I guess limiting the size of the custom data would be important, but given the current mods the biggest of these files is 314 bytes. And most of that is the description, which wouldn't be included in the data I'd like to see stored with the mod files. So I guess limiting the custom data to something like 512 bytes should be plenty.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.