Mass replace package types

This commit is contained in:
Armen 2022-02-15 21:04:19 -05:00
parent e4dcb89d2e
commit 311bfd2199
48 changed files with 264 additions and 264 deletions

View File

@ -89,7 +89,7 @@ def resolve_package_deps(out, package, only_hard, depth=1):
ret = []
out[id] = ret
if package.type != PackageType.MOD:
if package.type != PackageType.TOOL:
return
for dep in package.dependencies:
@ -106,7 +106,7 @@ def resolve_package_deps(out, package, only_hard, depth=1):
fulfilled_by = [ pkg.getId() for pkg in dep.meta_package.packages]
if depth == 1 and not dep.optional:
most_likely = next((pkg for pkg in dep.meta_package.packages if pkg.type == PackageType.MOD), None)
most_likely = next((pkg for pkg in dep.meta_package.packages if pkg.type == PackageType.TOOL), None)
if most_likely:
resolve_package_deps(out, most_likely, only_hard, depth + 1)
@ -470,9 +470,9 @@ def homepage():
featured = query.filter(Package.tags.any(name="featured")).order_by(
func.random()).limit(6).all()
new = query.order_by(db.desc(Package.approved_at)).limit(4).all()
pop_mod = query.filter_by(type=PackageType.MOD).order_by(db.desc(Package.score)).limit(8).all()
pop_mod = query.filter_by(type=PackageType.TOOL).order_by(db.desc(Package.score)).limit(8).all()
pop_gam = query.filter_by(type=PackageType.GAME).order_by(db.desc(Package.score)).limit(8).all()
pop_txp = query.filter_by(type=PackageType.TXP).order_by(db.desc(Package.score)).limit(8).all()
pop_txp = query.filter_by(type=PackageType.ASSETPACK).order_by(db.desc(Package.score)).limit(8).all()
high_reviewed = query.order_by(db.desc(Package.score - Package.score_downloads)) \
.filter(Package.reviews.any()).limit(4).all()

View File

@ -20,9 +20,9 @@ def home():
featured = query.filter(Package.tags.any(name="featured")).order_by(func.random()).limit(6).all()
new = join(query.order_by(db.desc(Package.approved_at))).limit(4).all()
pop_mod = join(query.filter_by(type=PackageType.MOD).order_by(db.desc(Package.score))).limit(8).all()
pop_mod = join(query.filter_by(type=PackageType.TOOL).order_by(db.desc(Package.score))).limit(8).all()
pop_gam = join(query.filter_by(type=PackageType.GAME).order_by(db.desc(Package.score))).limit(8).all()
pop_txp = join(query.filter_by(type=PackageType.TXP).order_by(db.desc(Package.score))).limit(8).all()
pop_txp = join(query.filter_by(type=PackageType.ASSETPACK).order_by(db.desc(Package.score))).limit(8).all()
high_reviewed = join(query.order_by(db.desc(Package.score - Package.score_downloads))) \
.filter(Package.reviews.any()).limit(4).all()

View File

@ -37,9 +37,9 @@ def game_hub(package: Package):
count = query.count()
new = join(query.order_by(db.desc(Package.approved_at))).limit(4).all()
pop_mod = join(query.filter_by(type=PackageType.MOD).order_by(db.desc(Package.score))).limit(8).all()
pop_mod = join(query.filter_by(type=PackageType.TOOL).order_by(db.desc(Package.score))).limit(8).all()
pop_gam = join(query.filter_by(type=PackageType.GAME).order_by(db.desc(Package.score))).limit(8).all()
pop_txp = join(query.filter_by(type=PackageType.TXP).order_by(db.desc(Package.score))).limit(8).all()
pop_txp = join(query.filter_by(type=PackageType.ASSETPACK).order_by(db.desc(Package.score))).limit(8).all()
high_reviewed = join(query.order_by(db.desc(Package.score - Package.score_downloads))) \
.filter(Package.reviews.any()).limit(4).all()

View File

@ -120,7 +120,7 @@ def view(package):
package.checkPerm(current_user, Permission.APPROVE_NEW))
conflicting_modnames = None
if show_similar and package.type != PackageType.TXP:
if show_similar and package.type != PackageType.ASSETPACK:
conflicting_modnames = db.session.query(MetaPackage.name) \
.filter(MetaPackage.id.in_([ mp.id for mp in package.provides ])) \
.filter(MetaPackage.packages.any(Package.id != package.id)) \
@ -136,9 +136,9 @@ def view(package):
conflicting_modnames = set([x[0] for x in conflicting_modnames])
packages_uses = None
if package.type == PackageType.MOD:
if package.type == PackageType.TOOL:
packages_uses = Package.query.filter(
Package.type == PackageType.MOD,
Package.type == PackageType.TOOL,
Package.id != package.id,
Package.state == PackageState.APPROVED,
Package.dependencies.any(
@ -164,7 +164,7 @@ def view(package):
if topic.author != package.author:
errors.append("<b>" + gettext("Error: Forum topic author doesn't match package author.") + "</b>")
topic_error_lvl = "danger"
elif package.type != PackageType.TXP:
elif package.type != PackageType.ASSETPACK:
errors.append(gettext("Warning: Forum topic not found. This may happen if the topic has only just been created."))
topic_error = "<br />".join(errors)
@ -226,7 +226,7 @@ def makeLabel(obj):
class PackageForm(FlaskForm):
type = SelectField(lazy_gettext("Type"), [InputRequired()], choices=PackageType.choices(), coerce=PackageType.coerce, default=PackageType.MOD)
type = SelectField(lazy_gettext("Type"), [InputRequired()], choices=PackageType.choices(), coerce=PackageType.coerce, default=PackageType.TOOL)
title = StringField(lazy_gettext("Title (Human-readable)"), [InputRequired(), Length(1, 100)])
name = StringField(lazy_gettext("Name (Technical)"), [InputRequired(), Length(1, 100), Regexp("^[a-z0-9_]+$", 0, lazy_gettext("Lower case letters (a-z), digits (0-9), and underscores (_) only"))])
short_desc = StringField(lazy_gettext("Short Description (Plaintext)"), [InputRequired(), Length(1,200)])
@ -293,7 +293,7 @@ def create_edit(author=None, name=None):
form.tags.data = package.tags
form.content_warnings.data = package.content_warnings
if request.method == "POST" and form.type.data == PackageType.TXP:
if request.method == "POST" and form.type.data == PackageType.ASSETPACK:
form.license.data = form.media_license.data
if form.validate_on_submit():

View File

@ -152,7 +152,7 @@ def get_user_medals(user: User) -> Tuple[List[Medal], List[Medal]]:
.all()
user_package_ranks = next(
(x for x in user_package_ranks if x[0] == PackageType.MOD or x[2] <= 10),
(x for x in user_package_ranks if x[0] == PackageType.TOOL or x[2] <= 10),
None)
if user_package_ranks:
top_rank = user_package_ranks[2]
@ -161,7 +161,7 @@ def get_user_medals(user: User) -> Tuple[List[Medal], List[Medal]]:
title = gettext(u"Top %(type)s", type=top_type.text.lower())
else:
title = gettext(u"Top %(group)d %(type)s", group=top_rank, type=top_type.text.lower())
if top_type == PackageType.MOD:
if top_type == PackageType.TOOL:
icon = "fa-box"
elif top_type == PackageType.GAME:
icon = "fa-gamepad"

View File

@ -69,25 +69,25 @@ def populate_test_data(session):
session.add(jeija)
mod = Package()
mod.state = PackageState.APPROVED
mod.name = "alpha"
mod.title = "Alpha Test"
mod.license = licenses["MIT"]
mod.media_license = licenses["MIT"]
mod.type = PackageType.MOD
mod.author = admin_user
mod.tags.append(tags["mapgen"])
mod.tags.append(tags["environment"])
mod.repo = "https://github.com/ezhh/other_worlds"
mod.issueTracker = "https://github.com/ezhh/other_worlds/issues"
mod.forums = 16015
mod.short_desc = "The content library should not be used yet as it is still in alpha"
mod.desc = "This is the long desc"
session.add(mod)
tool = Package()
tool.state = PackageState.APPROVED
tool.name = "alpha"
tool.title = "Alpha Test"
tool.license = licenses["MIT"]
tool.media_license = licenses["MIT"]
tool.type = PackageType.TOOL
tool.author = admin_user
tool.tags.append(tags["mapgen"])
tool.tags.append(tags["environment"])
tool.repo = "https://github.com/ezhh/other_worlds"
tool.issueTracker = "https://github.com/ezhh/other_worlds/issues"
tool.forums = 16015
tool.short_desc = "The content library should not be used yet as it is still in alpha"
tool.desc = "This is the long desc"
session.add(tool)
rel = PackageRelease()
rel.package = mod
rel.package = tool
rel.title = "v1.0.0"
rel.url = "https://github.com/ezhh/handholds/archive/master.zip"
rel.approved = True
@ -99,7 +99,7 @@ def populate_test_data(session):
mod1.title = "Awards"
mod1.license = licenses["LGPLv2.1"]
mod1.media_license = licenses["MIT"]
mod1.type = PackageType.MOD
mod1.type = PackageType.TOOL
mod1.author = admin_user
mod1.tags.append(tags["player_effects"])
mod1.repo = "https://github.com/rubenwardy/awards"
@ -135,7 +135,7 @@ awards.register_achievement("award_mesefind",{
mod2.name = "mesecons"
mod2.title = "Mesecons"
mod2.tags.append(tags["tools"])
mod2.type = PackageType.MOD
mod2.type = PackageType.TOOL
mod2.license = licenses["LGPLv3"]
mod2.media_license = licenses["MIT"]
mod2.author = jeija
@ -150,7 +150,7 @@ Mezzee-what?
------------
[Mesecons](http://mesecons.net/)! They're yellow, they're conductive, and they'll add a whole new dimension to Minetest's gameplay.
Mesecons is a mod for [Minetest](http://minetest.net/) that implements a ton of items related to digital circuitry, such as wires, buttons, lights, and even programmable controllers. Among other things, there are also pistons, solar panels, pressure plates, and note blocks.
Mesecons is a tool for [Minetest](http://minetest.net/) that implements a ton of items related to digital circuitry, such as wires, buttons, lights, and even programmable controllers. Among other things, there are also pistons, solar panels, pressure plates, and note blocks.
Mesecons has a similar goal to Redstone in Minecraft, but works in its own way, with different rules and mechanics.
@ -160,14 +160,14 @@ Go get it!
[DOWNLOAD IT NOW](https://github.com/minetest-mods/mesecons/archive/master.zip)
Now go ahead and install it like any other Minetest mod. Don't know how? Check out [the wonderful page about it](http://wiki.minetest.com/wiki/Mods) over at the Minetest Wiki. For your convenience, here's a quick summary:
Now go ahead and install it like any other Minetest tool. Don't know how? Check out [the wonderful page about it](http://wiki.minetest.com/wiki/Mods) over at the Minetest Wiki. For your convenience, here's a quick summary:
1. If Mesecons is still in a ZIP file, extract the folder inside to somewhere on the computer.
2. Make sure that when you open the folder, you can directly find `README.md` in the listing. If you just see another folder, move that folder up one level and delete the old one.
3. Open up the Minetest mods folder - usually `/mods/`. If you see the `minetest` or folder inside of that, that is your mod folder instead.
3. Open up the Minetest mods folder - usually `/mods/`. If you see the `minetest` or folder inside of that, that is your tool folder instead.
4. Copy the Mesecons folder into the mods folder.
Don't like some parts of Mesecons? Open up the Mesecons folder and delete the subfolder containing the mod you don't want. If you didn't want movestones, for example, all you have to do is delete the `mesecons_movestones` folder and they will no longer be available.
Don't like some parts of Mesecons? Open up the Mesecons folder and delete the subfolder containing the tool you don't want. If you didn't want movestones, for example, all you have to do is delete the `mesecons_movestones` folder and they will no longer be available.
There are no dependencies - it will work right after installing!
@ -219,79 +219,79 @@ No warranty is provided, express or implied, for any part of the project.
session.add(mod1)
session.add(mod2)
mod = Package()
mod.state = PackageState.APPROVED
mod.name = "handholds"
mod.title = "Handholds"
mod.license = licenses["MIT"]
mod.media_license = licenses["MIT"]
mod.type = PackageType.MOD
mod.author = ez
mod.tags.append(tags["player_effects"])
mod.repo = "https://github.com/ezhh/handholds"
mod.issueTracker = "https://github.com/ezhh/handholds/issues"
mod.forums = 17069
mod.short_desc = "Adds hand holds and climbing thingies"
mod.desc = "This is the long desc"
session.add(mod)
tool = Package()
tool.state = PackageState.APPROVED
tool.name = "handholds"
tool.title = "Handholds"
tool.license = licenses["MIT"]
tool.media_license = licenses["MIT"]
tool.type = PackageType.TOOL
tool.author = ez
tool.tags.append(tags["player_effects"])
tool.repo = "https://github.com/ezhh/handholds"
tool.issueTracker = "https://github.com/ezhh/handholds/issues"
tool.forums = 17069
tool.short_desc = "Adds hand holds and climbing thingies"
tool.desc = "This is the long desc"
session.add(tool)
rel = PackageRelease()
rel.package = mod
rel.package = tool
rel.title = "v1.0.0"
rel.max_rel = v4
rel.url = "https://github.com/ezhh/handholds/archive/master.zip"
rel.approved = True
session.add(rel)
mod = Package()
mod.state = PackageState.APPROVED
mod.name = "other_worlds"
mod.title = "Other Worlds"
mod.license = licenses["MIT"]
mod.media_license = licenses["MIT"]
mod.type = PackageType.MOD
mod.author = ez
mod.tags.append(tags["mapgen"])
mod.tags.append(tags["environment"])
mod.repo = "https://github.com/ezhh/other_worlds"
mod.issueTracker = "https://github.com/ezhh/other_worlds/issues"
mod.forums = 16015
mod.short_desc = "Adds space with asteroids and comets"
mod.desc = "This is the long desc"
session.add(mod)
tool = Package()
tool.state = PackageState.APPROVED
tool.name = "other_worlds"
tool.title = "Other Worlds"
tool.license = licenses["MIT"]
tool.media_license = licenses["MIT"]
tool.type = PackageType.TOOL
tool.author = ez
tool.tags.append(tags["mapgen"])
tool.tags.append(tags["environment"])
tool.repo = "https://github.com/ezhh/other_worlds"
tool.issueTracker = "https://github.com/ezhh/other_worlds/issues"
tool.forums = 16015
tool.short_desc = "Adds space with asteroids and comets"
tool.desc = "This is the long desc"
session.add(tool)
mod = Package()
mod.state = PackageState.APPROVED
mod.name = "food"
mod.title = "Food"
mod.license = licenses["LGPLv2.1"]
mod.media_license = licenses["MIT"]
mod.type = PackageType.MOD
mod.author = admin_user
mod.tags.append(tags["player_effects"])
mod.repo = "https://github.com/rubenwardy/food/"
mod.issueTracker = "https://github.com/rubenwardy/food/issues/"
mod.forums = 2960
mod.short_desc = "Adds lots of food and an API to manage ingredients"
mod.desc = "This is the long desc"
session.add(mod)
tool = Package()
tool.state = PackageState.APPROVED
tool.name = "food"
tool.title = "Food"
tool.license = licenses["LGPLv2.1"]
tool.media_license = licenses["MIT"]
tool.type = PackageType.TOOL
tool.author = admin_user
tool.tags.append(tags["player_effects"])
tool.repo = "https://github.com/rubenwardy/food/"
tool.issueTracker = "https://github.com/rubenwardy/food/issues/"
tool.forums = 2960
tool.short_desc = "Adds lots of food and an API to manage ingredients"
tool.desc = "This is the long desc"
session.add(tool)
mod = Package()
mod.state = PackageState.APPROVED
mod.name = "food_sweet"
mod.title = "Sweet Foods"
mod.license = licenses["CC0"]
mod.media_license = licenses["MIT"]
mod.type = PackageType.MOD
mod.author = admin_user
mod.tags.append(tags["player_effects"])
mod.repo = "https://github.com/rubenwardy/food_sweet/"
mod.issueTracker = "https://github.com/rubenwardy/food_sweet/issues/"
mod.forums = 9039
mod.short_desc = "Adds sweet food"
mod.desc = "This is the long desc"
food_sweet = mod
session.add(mod)
tool = Package()
tool.state = PackageState.APPROVED
tool.name = "food_sweet"
tool.title = "Sweet Foods"
tool.license = licenses["CC0"]
tool.media_license = licenses["MIT"]
tool.type = PackageType.TOOL
tool.author = admin_user
tool.tags.append(tags["player_effects"])
tool.repo = "https://github.com/rubenwardy/food_sweet/"
tool.issueTracker = "https://github.com/rubenwardy/food_sweet/issues/"
tool.forums = 9039
tool.short_desc = "Adds sweet food"
tool.desc = "This is the long desc"
food_sweet = tool
session.add(tool)
game1 = Package()
game1.state = PackageState.APPROVED
@ -356,21 +356,21 @@ Uses the CTF PvP Engine.
session.add(rel)
mod = Package()
mod.state = PackageState.APPROVED
mod.name = "pixelbox"
mod.title = "PixelBOX Reloaded"
mod.license = licenses["CC0"]
mod.media_license = licenses["MIT"]
mod.type = PackageType.TXP
mod.author = admin_user
mod.forums = 14132
mod.short_desc = "This is an update of the original PixelBOX texture pack by the brillant artist Gambit"
mod.desc = "This is the long desc"
session.add(mod)
tool = Package()
tool.state = PackageState.APPROVED
tool.name = "pixelbox"
tool.title = "PixelBOX Reloaded"
tool.license = licenses["CC0"]
tool.media_license = licenses["MIT"]
tool.type = PackageType.ASSETPACK
tool.author = admin_user
tool.forums = 14132
tool.short_desc = "This is an update of the original PixelBOX texture pack by the brillant artist Gambit"
tool.desc = "This is the long desc"
session.add(tool)
rel = PackageRelease()
rel.package = mod
rel.package = tool
rel.title = "v1.0.0"
rel.url = "http://mamadou3.free.fr/Minetest/PixelBOX.zip"
rel.approved = True
@ -379,7 +379,7 @@ Uses the CTF PvP Engine.
session.commit()
metas = {}
for package in Package.query.filter_by(type=PackageType.MOD).all():
for package in Package.query.filter_by(type=PackageType.TOOL).all():
meta = None
try:
meta = metas[package.name]

View File

@ -74,7 +74,7 @@ Tokens can be attained by visiting [Settings > API Tokens](/user/tokens/).
* PUT `/api/packages/<author>/<name>/` (Update)
* Requires authentication.
* JSON dictionary with any of these keys (all are optional, null to delete Nullables):
* `type`: One of `GAME`, `MOD`, `TXP`.
* `type`: One of `GAME`, `TOOL`, `ASSETPACK`.
* `title`: Human-readable title.
* `name`: Technical name (needs permission if already approved).
* `short_description`
@ -99,10 +99,10 @@ Tokens can be attained by visiting [Settings > API Tokens](/user/tokens/).
* Supports [Package Queries](#package-queries)
* [Paginated result](#paginated-results), max 300 results per page
* Each item in `items` will be a dictionary with the following keys:
* `type`: One of `GAME`, `MOD`, `TXP`.
* `type`: One of `GAME`, `TOOL`, `ASSETPACK`.
* `author`: Username of the package author.
* `name`: Package name.
* `provides`: List of technical mod names inside the package.
* `provides`: List of technical tool names inside the package.
* `depends`: List of hard dependencies.
* Each dep will either be a metapackage dependency (`name`), or a
package dependency (`author/name`).
@ -134,11 +134,11 @@ curl -X PUT https://content.minetest.net/api/packages/username/name/ \
Example:
/api/packages/?type=mod&type=game&q=mobs+fun&hide=nonfree&hide=gore
/api/packages/?type=tool&type=game&q=mobs+fun&hide=nonfree&hide=gore
Supported query parameters:
* `type`: Package types (`mod`, `game`, `txp`).
* `type`: Package types (`tool`, `game`, `asset_pack`).
* `q`: Query string.
* `author`: Filter by author.
* `tag`: Filter by tags.
@ -173,7 +173,7 @@ Supported query parameters:
* `package`
* `author`: author username
* `name`: technical name
* `type`: `mod`, `game`, or `txp`
* `type`: `tool`, `game`, or `asset_pack`
* GET `/api/packages/<username>/<name>/releases/` (List)
* Returns array of release dictionaries, see above, but without package info.
* GET `/api/packages/<username>/<name>/releases/<id>/` (Read)
@ -304,7 +304,7 @@ Example:
```json
[
{
"comment": "This is a really good mod!",
"comment": "This is a really good tool!",
"created_at": "2021-11-24T16:18:33.764084",
"is_positive": true,
"title": "Really good",
@ -330,12 +330,12 @@ Example:
Example:
/api/topics/?q=mobs&type=mod&type=game
/api/topics/?q=mobs&type=tool&type=game
Supported query parameters:
* `q`: Query string.
* `type`: Package types (`mod`, `game`, `txp`).
* `type`: Package types (`tool`, `game`, `asset_pack`).
* `sort`: Sort by (`name`, `views`, `created_at`).
* `show_added`: Show topics that have an existing package.
* `show_discarded`: Show topics marked as discarded.

View File

@ -69,8 +69,8 @@ is available.
* MUST: `screenshot.png` is present and up-to-date, with a correct aspect ratio (3:2, at least 300x200).
* MUST: Have a high resolution cover image on ContentDB (at least 1280x720 pixels).
It may be shown cropped to 16:9 aspect ratio, or shorter.
* MUST: mod.conf/game.conf/texture_pack.conf present with:
* name (if mod or game)
* MUST: tool.conf/game.conf/texture_pack.conf present with:
* name (if tool or game)
* description
* dependencies (if relevant)
* `min_minetest_version` and `max_minetest_version` (if relevant)

View File

@ -14,7 +14,7 @@ and they will be subject to limited promotion.
of packages with non-free licenses.**
Minetest is free and open source software, and is only as big as it is now
because of this. It's pretty amazing you can take nearly any published mod and modify it
because of this. It's pretty amazing you can take nearly any published tool and modify it
to how you like - add some features, maybe fix some bugs - and then share those
modifications without the worry of legal issues. The project, itself, relies on open
source contributions to survive - if it were non-free, then it would have died

View File

@ -14,8 +14,8 @@ Every type of content can have a `.conf` file that contains the metadata.
The filename of the `.conf` file depends on the content type:
* `mod.conf` for mods.
* `modpack.conf` for mod packs.
* `tool.conf` for mods.
* `modpack.conf` for tool packs.
* `game.conf` for games.
* `texture_pack.conf` for texture packs.
@ -36,7 +36,7 @@ ContentDB understands the following information:
and for mods only:
* `name` - the mod technical name.
* `name` - the tool technical name.
## .cdb.json
@ -46,7 +46,7 @@ to update the package meta.
It should be a JSON dictionary with one or more of the following optional keys:
* `type`: One of `GAME`, `MOD`, `TXP`.
* `type`: One of `GAME`, `TOOL`, `ASSETPACK`.
* `title`: Human-readable title.
* `name`: Technical name (needs permission if already approved).
* `short_description`

View File

@ -8,7 +8,7 @@ the listings and to combat abuse.
* **No inappropriate content.** <sup>2.1</sup>
* **Content must be playable/useful, but not necessarily finished.** <sup>2.2</sup>
* **Don't use the name of another mod unless your mod is a fork or reimplementation.** <sup>3</sup>
* **Don't use the name of another tool unless your tool is a fork or reimplementation.** <sup>3</sup>
* **Licenses must allow derivatives, redistribution, and must not discriminate.** <sup>4</sup>
* **Don't put promotions or advertisements in any package metadata.** <sup>5</sup>
* **The ContentDB admin reserves the right to remove packages for any reason**,
@ -51,14 +51,14 @@ as this will help advise players.
Adding non-player facing mods, such as libraries and server tools, is perfectly fine
and encouraged. ContentDB isn't just for player-facing things, and adding
libraries allows them to be installed when a mod depends on it.
libraries allows them to be installed when a tool depends on it.
## 3. Technical Names
### 3.1 Right to a name
A package uses a name when it has that name or contains a mod that uses that name.
A package uses a name when it has that name or contains a tool that uses that name.
The first package to use a name based on the creation of its forum topic or
ContentDB submission has the right to the technical name. The use of a package
@ -74,14 +74,14 @@ to change the name of the package, or your package won't be accepted.
We reserve the right to issue exceptions for this where we feel necessary.
### 3.2. Mod Forks and Reimplementations
### 3.2. Tool Forks and Reimplementations
An exception to the above is that mods are allowed to have the same name as a
mod if it's a fork of that mod (or a close reimplementation). In real terms, it
should be possible to use the new mod as a drop-in replacement.
tool if it's a fork of that tool (or a close reimplementation). In real terms, it
should be possible to use the new tool as a drop-in replacement.
We reserve the right to decide whether a mod counts as a fork or
reimplementation of the mod that owns the name.
We reserve the right to decide whether a tool counts as a fork or
reimplementation of the tool that owns the name.
## 4. Licenses

View File

@ -83,9 +83,9 @@ Please [raise a report](https://content.minetest.net/report/?anon=0) if you
wish to remove your personal information.
ContentDB keeps a record of each username and forum topic on the forums,
for use in indexing mod/game topics. ContentDB also requires the use of a username
for use in indexing tool/game topics. ContentDB also requires the use of a username
to uniquely identify a package. Therefore, an author cannot be removed completely
from ContentDB if they have any packages or mod/game topics on the forum.
from ContentDB if they have any packages or tool/game topics on the forum.
If we are unable to remove your account for one of the above reasons, your user
account will instead be wiped and deactivated, ending up exactly like an author

View File

@ -140,8 +140,8 @@ class GameSupportResolver:
self.checked_packages.add(key)
if package.type != PackageType.MOD:
raise LogicError(500, "Got non-mod")
if package.type != PackageType.TOOL:
raise LogicError(500, "Got non-tool")
retval = PackageSet()
@ -160,7 +160,7 @@ class GameSupportResolver:
return retval
def update_all(self) -> None:
for package in Package.query.filter(Package.type == PackageType.MOD, Package.state != PackageState.DELETED).all():
for package in Package.query.filter(Package.type == PackageType.TOOL, Package.state != PackageState.DELETED).all():
retval = self.resolve(package, [])
for game in retval:
support = PackageGameSupport(package, game)

View File

@ -140,10 +140,10 @@ def do_edit_package(user: User, package: Package, was_new: bool, was_web: bool,
if key in data:
setattr(package, key, data[key])
if package.type == PackageType.TXP:
if package.type == PackageType.ASSETPACK:
package.license = package.media_license
if was_new and package.type == PackageType.MOD:
if was_new and package.type == PackageType.TOOL:
m = MetaPackage.GetOrCreate(package.name, {})
package.provides.append(m)

View File

@ -49,9 +49,9 @@ class License(db.Model):
class PackageType(enum.Enum):
MOD = "Mod"
GAME = "Game"
TXP = "Texture Pack"
TOOL = "Tool"
GAME = "Game"
ASSETPACK = "Asset Pack"
def toName(self):
return self.name.lower()
@ -61,20 +61,20 @@ class PackageType(enum.Enum):
@property
def text(self):
if self == PackageType.MOD:
return lazy_gettext("Mod")
if self == PackageType.TOOL:
return lazy_gettext("Tool")
elif self == PackageType.GAME:
return lazy_gettext("Game")
elif self == PackageType.TXP:
return lazy_gettext("Texture Pack")
elif self == PackageType.ASSETPACK:
return lazy_gettext("Asset Pack")
@property
def plural(self):
if self == PackageType.MOD:
if self == PackageType.TOOL:
return lazy_gettext("Mods")
elif self == PackageType.GAME:
return lazy_gettext("Games")
elif self == PackageType.TXP:
elif self == PackageType.ASSETPACK:
return lazy_gettext("Texture Packs")
@classmethod
@ -728,7 +728,7 @@ class Package(db.Model):
return False
needsScreenshot = \
(self.type == self.type.GAME or self.type == self.type.TXP) and \
(self.type == self.type.GAME or self.type == self.type.ASSETPACK) and \
self.screenshots.count() == 0
return self.releases.filter(PackageRelease.task_id.is_(None)).count() > 0 and not needsScreenshot

File diff suppressed because one or more lines are too long

View File

@ -53,7 +53,7 @@ ni:" ac co com edu gob mil net nom org ",np:" com edu gov mil net org ",nr:" biz
ps:" com edu gov net org plo sec ",pw:" belau co ed go ne or ",ro:" arts com firm info nom nt org rec store tm www ",rs:" ac co edu gov in org ",sb:" com edu gov net org ",sc:" com edu gov net org ",sh:" co com edu gov net nom org ",sl:" com edu gov net org ",st:" co com consulado edu embaixada gov mil net org principe saotome store ",sv:" com edu gob org red ",sz:" ac co org ",tr:" av bbs bel biz com dr edu gen gov info k12 name net org pol tel tsk tv web ",tt:" aero biz cat co com coop edu gov info int jobs mil mobi museum name net org pro tel travel ",
tw:" club com ebiz edu game gov idv mil net org ",mu:" ac co com gov net or org ",mz:" ac co edu gov org ",na:" co com ",nz:" ac co cri geek gen govt health iwi maori mil net org parliament school ",pa:" abo ac com edu gob ing med net nom org sld ",pt:" com edu gov int net nome org publ ",py:" com edu gov mil net org ",qa:" com edu gov mil net org ",re:" asso com nom ",ru:" ac adygeya altai amur arkhangelsk astrakhan bashkiria belgorod bir bryansk buryatia cbg chel chelyabinsk chita chukotka chuvashia com dagestan e-burg edu gov grozny int irkutsk ivanovo izhevsk jar joshkar-ola kalmykia kaluga kamchatka karelia kazan kchr kemerovo khabarovsk khakassia khv kirov koenig komi kostroma kranoyarsk kuban kurgan kursk lipetsk magadan mari mari-el marine mil mordovia mosreg msk murmansk nalchik net nnov nov novosibirsk nsk omsk orenburg org oryol penza perm pp pskov ptz rnd ryazan sakhalin samara saratov simbirsk smolensk spb stavropol stv surgut tambov tatarstan tom tomsk tsaritsyn tsk tula tuva tver tyumen udm udmurtia ulan-ude vladikavkaz vladimir vladivostok volgograd vologda voronezh vrn vyatka yakutia yamal yekaterinburg yuzhno-sakhalinsk ",
rw:" ac co com edu gouv gov int mil net ",sa:" com edu gov med net org pub sch ",sd:" com edu gov info med net org tv ",se:" a ac b bd c d e f g h i k l m n o org p parti pp press r s t tm u w x y z ",sg:" com edu gov idn net org per ",sn:" art com edu gouv org perso univ ",sy:" com edu gov mil net news org ",th:" ac co go in mi net or ",tj:" ac biz co com edu go gov info int mil name net nic org test web ",tn:" agrinet com defense edunet ens fin gov ind info intl mincom nat net org perso rnrt rns rnu tourism ",
tz:" ac co go ne or ",ua:" biz cherkassy chernigov chernovtsy ck cn co com crimea cv dn dnepropetrovsk donetsk dp edu gov if in ivano-frankivsk kh kharkov kherson khmelnitskiy kiev kirovograd km kr ks kv lg lugansk lutsk lviv me mk net nikolaev od odessa org pl poltava pp rovno rv sebastopol sumy te ternopil uzhgorod vinnica vn zaporizhzhe zhitomir zp zt ",ug:" ac co go ne or org sc ",uk:" ac bl british-library co cym gov govt icnet jet lea ltd me mil mod national-library-scotland nel net nhs nic nls org orgn parliament plc police sch scot soc ",
tz:" ac co go ne or ",ua:" biz cherkassy chernigov chernovtsy ck cn co com crimea cv dn dnepropetrovsk donetsk dp edu gov if in ivano-frankivsk kh kharkov kherson khmelnitskiy kiev kirovograd km kr ks kv lg lugansk lutsk lviv me mk net nikolaev od odessa org pl poltava pp rovno rv sebastopol sumy te ternopil uzhgorod vinnica vn zaporizhzhe zhitomir zp zt ",ug:" ac co go ne or org sc ",uk:" ac bl british-library co cym gov govt icnet jet lea ltd me mil tool national-library-scotland nel net nhs nic nls org orgn parliament plc police sch scot soc ",
us:" dni fed isa kids nsn ",uy:" com edu gub mil net org ",ve:" co com edu gob info mil net org web ",vi:" co com k12 net org ",vn:" ac biz com edu gov health info int name net org pro ",ye:" co com gov ltd me net org plc ",yu:" ac co edu gov org ",za:" ac agric alt bourse city co cybernet db edu gov grondar iaccess imt inca landesign law mil net ngo nis nom olivetti org pix school tm web ",zm:" ac co com edu gov net org sch ",com:"ar br cn de eu gb gr hu jpn kr no qc ru sa se uk us uy za ",net:"gb jp se uk ",
org:"ae",de:"com "},has:function(k){var d=k.lastIndexOf(".");if(0>=d||d>=k.length-1)return!1;var m=k.lastIndexOf(".",d-1);if(0>=m||m>=d-1)return!1;var x=n.list[k.slice(d+1)];return x?0<=x.indexOf(" "+k.slice(m+1,d)+" "):!1},is:function(k){var d=k.lastIndexOf(".");if(0>=d||d>=k.length-1||0<=k.lastIndexOf(".",d-1))return!1;var m=n.list[k.slice(d+1)];return m?0<=m.indexOf(" "+k.slice(0,d)+" "):!1},get:function(k){var d=k.lastIndexOf(".");if(0>=d||d>=k.length-1)return null;var m=k.lastIndexOf(".",d-1);
if(0>=m||m>=d-1)return null;var x=n.list[k.slice(d+1)];return!x||0>x.indexOf(" "+k.slice(m+1,d)+" ")?null:k.slice(m+1)},noConflict:function(){t.SecondLevelDomains===this&&(t.SecondLevelDomains=w);return this}};return n});

View File

@ -4,6 +4,6 @@
<LongName>ContentDB</LongName>
<InputEncoding>UTF-8</InputEncoding>
<Description>Search mods, games, and textures for Minetest.</Description>
<Tags>Minetest Mod Game Subgame Search</Tags>
<Tags>Minetest Tool Game Subgame Search</Tags>
<Url type="text/html" method="get" template="https://content.minetest.net/packages?q={searchTerms}"/>
</OpenSearchDescription>

View File

@ -38,7 +38,7 @@ $(function() {
}
let hint_mtmods = `Tip:
Don't include <i>Minetest</i>, <i>mod</i>, or <i>modpack</i> anywhere in the short description.
Don't include <i>Minetest</i>, <i>tool</i>, or <i>modpack</i> anywhere in the short description.
It is unnecessary and wastes characters.`;
let hint_thegame = `Tip:
@ -47,8 +47,8 @@ $(function() {
$("#short_desc").on("change paste keyup", function() {
const val = $(this).val().toLowerCase();
if (val.indexOf("minetest") >= 0 || val.indexOf("mod") >= 0 ||
val.indexOf("modpack") >= 0 || val.indexOf("mod pack") >= 0) {
if (val.indexOf("minetest") >= 0 || val.indexOf("tool") >= 0 ||
val.indexOf("modpack") >= 0 || val.indexOf("tool pack") >= 0) {
showHint($(this), hint_mtmods);
} else if (val.indexOf("the game") >= 0) {
showHint($(this), hint_thegame);

View File

@ -80,7 +80,7 @@ def checkAllForumAccounts(forceNoSave=False):
regex_tag = re.compile(r"\[([a-z0-9_]+)\]")
BANNED_NAMES = ["mod", "game", "old", "outdated", "wip", "api", "beta", "alpha", "git"]
BANNED_NAMES = ["tool", "game", "old", "outdated", "wip", "api", "beta", "alpha", "git"]
def getNameFromTaglist(taglist):
for tag in reversed(regex_tag.findall(taglist)):
if len(tag) < 30 and not tag in BANNED_NAMES and \
@ -112,7 +112,7 @@ def getLinksFromModSearch():
pass
except urllib.error.URLError:
print("Unable to open krocks mod search!")
print("Unable to open krocks tool search!")
return links
return links
@ -122,8 +122,8 @@ def importTopicList():
links_by_id = getLinksFromModSearch()
info_by_id = {}
getTopicsFromForum(11, out=info_by_id, extra={ 'type': PackageType.MOD, 'wip': False })
getTopicsFromForum(9, out=info_by_id, extra={ 'type': PackageType.MOD, 'wip': True })
getTopicsFromForum(11, out=info_by_id, extra={ 'type': PackageType.TOOL, 'wip': False })
getTopicsFromForum(9, out=info_by_id, extra={ 'type': PackageType.TOOL, 'wip': True })
getTopicsFromForum(15, out=info_by_id, extra={ 'type': PackageType.GAME, 'wip': False })
getTopicsFromForum(50, out=info_by_id, extra={ 'type': PackageType.GAME, 'wip': True })

View File

@ -78,7 +78,7 @@ def postReleaseCheckUpdate(self, release: PackageRelease, path):
tree = build_tree(path, expected_type=ContentType[release.package.type.name],
author=release.package.author.username, name=release.package.name)
if tree.name is not None and release.package.name != tree.name and tree.type == ContentType.MOD:
if tree.name is not None and release.package.name != tree.name and tree.type == ContentType.TOOL:
raise MinetestCheckError(f"Expected {tree.relative} to have technical name {release.package.name}, instead has name {tree.name}")
cache = {}
@ -99,9 +99,9 @@ def postReleaseCheckUpdate(self, release: PackageRelease, path):
optional_depends = tree.fold("meta", "optional_depends")
# Filter out provides
for mod in provides:
depends.discard(mod)
optional_depends.discard(mod)
for tool in provides:
depends.discard(tool)
optional_depends.discard(tool)
# Raise error on unresolved game dependencies
if package.type == PackageType.GAME and len(depends) > 0:
@ -116,7 +116,7 @@ def postReleaseCheckUpdate(self, release: PackageRelease, path):
db.session.add(Dependency(package, meta=meta, optional=True))
# Update game supports
if package.type == PackageType.MOD:
if package.type == PackageType.TOOL:
resolver = GameSupportResolver()
resolver.update(package)

View File

@ -8,13 +8,13 @@ class MinetestCheckError(Exception):
class ContentType(Enum):
UNKNOWN = "unknown"
MOD = "mod"
TOOL = "tool"
MODPACK = "modpack"
GAME = "game"
TXP = "texture pack"
ASSETPACK = "texture pack"
def isModLike(self):
return self == ContentType.MOD or self == ContentType.MODPACK
return self == ContentType.TOOL or self == ContentType.MODPACK
def validate_same(self, other):
"""
@ -22,12 +22,12 @@ class ContentType(Enum):
"""
assert other
if self == ContentType.MOD:
if self == ContentType.TOOL:
if not other.isModLike():
raise MinetestCheckError("Expected a mod or modpack, found " + other.value)
raise MinetestCheckError("Expected a tool or modpack, found " + other.value)
elif self == ContentType.TXP:
if other != ContentType.UNKNOWN and other != ContentType.TXP:
elif self == ContentType.ASSETPACK:
if other != ContentType.UNKNOWN and other != ContentType.ASSETPACK:
raise MinetestCheckError("expected a " + self.value + ", found a " + other.value)
elif other != self:

View File

@ -19,14 +19,14 @@ def detect_type(path):
if os.path.isfile(path + "/game.conf"):
return ContentType.GAME
elif os.path.isfile(path + "/init.lua"):
return ContentType.MOD
return ContentType.TOOL
elif os.path.isfile(path + "/modpack.txt") or \
os.path.isfile(path + "/modpack.conf"):
return ContentType.MODPACK
# elif os.path.isdir(path + "/mods"):
# return ContentType.GAME
elif os.path.isfile(path + "/texture_pack.conf"):
return ContentType.TXP
return ContentType.ASSETPACK
else:
return ContentType.UNKNOWN
@ -56,9 +56,9 @@ class PackageTreeNode:
if not os.path.isdir(baseDir + "/mods"):
raise MinetestCheckError("Game at {} does not have a mods/ folder".format(self.relative))
self.add_children_from_mod_dir("mods")
elif self.type == ContentType.MOD:
elif self.type == ContentType.TOOL:
if self.name and not basenamePattern.match(self.name):
raise MinetestCheckError("Invalid base name for mod {} at {}, names must only contain a-z0-9_." \
raise MinetestCheckError("Invalid base name for tool {} at {}, names must only contain a-z0-9_." \
.format(self.name, self.relative))
elif self.type == ContentType.MODPACK:
self.add_children_from_mod_dir(None)
@ -72,11 +72,11 @@ class PackageTreeNode:
def getMetaFileName(self):
if self.type == ContentType.GAME:
return "game.conf"
elif self.type == ContentType.MOD:
return "mod.conf"
elif self.type == ContentType.TOOL:
return "tool.conf"
elif self.type == ContentType.MODPACK:
return "modpack.conf"
elif self.type == ContentType.TXP:
elif self.type == ContentType.ASSETPACK:
return "texture_pack.conf"
else:
return None
@ -143,11 +143,11 @@ class PackageTreeNode:
for dep in deps:
if not basenamePattern.match(dep):
if " " in dep:
raise MinetestCheckError("Invalid dependency name '{}' for mod at {}, did you forget a comma?" \
raise MinetestCheckError("Invalid dependency name '{}' for tool at {}, did you forget a comma?" \
.format(dep, self.relative))
else:
raise MinetestCheckError(
"Invalid dependency name '{}' for mod at {}, names must only contain a-z0-9_." \
"Invalid dependency name '{}' for tool at {}, names must only contain a-z0-9_." \
.format(dep, self.relative))
# Check dependencies
@ -188,16 +188,16 @@ class PackageTreeNode:
if not entry.startswith('.') and os.path.isdir(path):
child = PackageTreeNode(path, relative + entry + "/", name=entry)
if not child.type.isModLike():
raise MinetestCheckError("Expecting mod or modpack, found {} at {} inside {}" \
raise MinetestCheckError("Expecting tool or modpack, found {} at {} inside {}" \
.format(child.type.value, child.relative, self.type.value))
if child.name is None:
raise MinetestCheckError("Missing base name for mod at {}".format(self.relative))
raise MinetestCheckError("Missing base name for tool at {}".format(self.relative))
self.children.append(child)
def getModNames(self):
return self.fold("name", type=ContentType.MOD)
return self.fold("name", type=ContentType.TOOL)
# attr: Attribute name
# key: Key in attribute

View File

@ -24,13 +24,13 @@
<div class="collapse navbar-collapse" id="navbarColor01">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" href="{{ url_for('packages.list_all', type='mod') }}">{{ _("Mods") }}</a>
<a class="nav-link" href="{{ url_for('packages.list_all', type='tool') }}">{{ _("Mods") }}</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('packages.list_all', type='game') }}">{{ _("Games") }}</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('packages.list_all', type='txp') }}">{{ _("Texture Packs") }}</a>
<a class="nav-link" href="{{ url_for('packages.list_all', type='asset_pack') }}">{{ _("Texture Packs") }}</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('packages.list_all', random=1, lucky=1) }}">{{ _("Random") }}</a>

View File

@ -118,14 +118,14 @@
{{ render_pkggrid(pop_gam) }}
<a href="{{ url_for('packages.list_all', type='mod', sort='score', order='desc') }}" class="btn btn-secondary float-right">
<a href="{{ url_for('packages.list_all', type='tool', sort='score', order='desc') }}" class="btn btn-secondary float-right">
{{ _("See more") }}
</a>
<h2 class="my-3">{{ _("Top Mods") }}</h2>
{{ render_pkggrid(pop_mod) }}
<a href="{{ url_for('packages.list_all', type='txp', sort='score', order='desc') }}" class="btn btn-secondary float-right">
<a href="{{ url_for('packages.list_all', type='asset_pack', sort='score', order='desc') }}" class="btn btn-secondary float-right">
{{ _("See more") }}
</a>
<h2 class="my-3">{{ _("Top Texture Packs") }}</h2>

View File

@ -37,7 +37,7 @@
{% endif %}
{% endset %}
{% elif (package.type == package.type.GAME or package.type == package.type.TXP) and package.screenshots.count() == 0 %}
{% elif (package.type == package.type.GAME or package.type == package.type.ASSETPACK) and package.screenshots.count() == 0 %}
{% set message = _("You need to add at least one screenshot.") %}
{% elif package.getMissingHardDependenciesQuery().count() > 0 %}

View File

@ -20,11 +20,11 @@
{{ package.short_desc }}
</p>
{% if not package.license.is_foss and not package.media_license.is_foss and package.type != package.type.TXP %}
{% if not package.license.is_foss and not package.media_license.is_foss and package.type != package.type.ASSETPACK %}
<p style="color:#f33;">
{{ _("<b>Warning:</b> Non-free code and media.") }}
</p>
{% elif not package.license.is_foss and package.type != package.type.TXP %}
{% elif not package.license.is_foss and package.type != package.type.ASSETPACK %}
<p style="color:#f33;">
{{ _("<b>Warning:</b> Non-free code.") }}
</p>

View File

@ -15,7 +15,7 @@
{{ render_pkggrid(mpackage.packages.filter_by(type="GAME", state="APPROVED").all()) }}
<h3>{{ _("Mods") }}</h3>
{{ render_pkggrid(mpackage.packages.filter_by(type="MOD", state="APPROVED").all()) }}
{{ render_pkggrid(mpackage.packages.filter_by(type="TOOL", state="APPROVED").all()) }}
{% if similar_topics %}
<h3>{{ _("Forum Topics") }}</h3>

View File

@ -41,7 +41,7 @@
{{ render_pkggrid(updated) }}
<a href="{{ url_for('packages.list_all', type='mod', sort='score', order='desc', game=package.getId()) }}" class="btn btn-secondary float-right">
<a href="{{ url_for('packages.list_all', type='tool', sort='score', order='desc', game=package.getId()) }}" class="btn btn-secondary float-right">
{{ _("See more") }}
</a>
<h2 class="my-3">{{ _("Top Mods") }}</h2>

View File

@ -50,11 +50,11 @@
{% endif %}
</a>
{% if package.type == package.type.MOD %}
{% if package.type == package.type.TOOL %}
{% set installing_url = "https://wiki.minetest.net/Installing_Mods" %}
{% elif package.type == package.type.GAME %}
{% set installing_url = "https://wiki.minetest.net/Games#Installing_games" %}
{% elif package.type == package.type.TXP %}
{% elif package.type == package.type.ASSETPACK %}
{% set installing_url = "https://wiki.minetest.net/Installing_Texture_Packs" %}
{% else %}
{{ 0 / 0 }}
@ -76,9 +76,9 @@
{% endblock %}
{% block container %}
{% if not package.license.is_foss and not package.media_license.is_foss and package.type != package.type.TXP %}
{% if not package.license.is_foss and not package.media_license.is_foss and package.type != package.type.ASSETPACK %}
{% set package_warning=_("Non-free code and media") %}
{% elif not package.license.is_foss and package.type != package.type.TXP %}
{% elif not package.license.is_foss and package.type != package.type.ASSETPACK %}
{% set package_warning=_("Non-free code") %}
{% elif not package.media_license.is_foss %}
{% set package_warning=_("Non-free media") %}
@ -384,7 +384,7 @@
</a>
{% endif %}
{% if package.type != package.type.TXP %}
{% if package.type != package.type.ASSETPACK %}
<h3>{{ _("Dependencies") }}</h3>
<dl>
<dt>{{ _("Required") }}</dt>
@ -432,7 +432,7 @@
</dl>
{% endif %}
{% if package.type == package.type.MOD %}
{% if package.type == package.type.TOOL %}
<h3>{{ _("Compatible Games") }}</h3>
{% for support in package.getSortedSupportedGames() %}
<a class="badge badge-secondary"
@ -462,7 +462,7 @@
<dd>
{% if package.license == package.media_license %}
{{ render_license(package.license) }}
{% elif package.type == package.type.TXP %}
{% elif package.type == package.type.ASSETPACK %}
{{ render_license(package.media_license) }}
{% else %}
{{ _("%(code_license)s for code,<br>%(media_license)s for media.",

View File

@ -10,23 +10,23 @@ def make_package(name: str, versions: List[Tuple[Optional[str], Optional[str]]])
license = License.query.filter_by(name="MIT").first()
author = User.query.first()
mod = Package()
mod.state = PackageState.APPROVED
mod.name = name.lower()
mod.title = name
mod.license = license
mod.media_license = license
mod.type = PackageType.MOD
mod.author = author
mod.short_desc = "The content library should not be used yet as it is still in alpha"
mod.desc = "This is the long desc"
db.session.add(mod)
tool = Package()
tool.state = PackageState.APPROVED
tool.name = name.lower()
tool.title = name
tool.license = license
tool.media_license = license
tool.type = PackageType.TOOL
tool.author = author
tool.short_desc = "The content library should not be used yet as it is still in alpha"
tool.desc = "This is the long desc"
db.session.add(tool)
rels = []
for (minv, maxv) in versions:
rel = PackageRelease()
rel.package = mod
rel.package = tool
rel.title = "test"
rel.url = "https://github.com/ezhh/handholds/archive/master.zip"

View File

@ -13,7 +13,7 @@ The query arguments will include a list of supported types, the current
and any hidden [Content Flags](https://content.minetest.net/help/content_flags/).
Example URL:
<https://content.minetest.net/api/packages/?type=mod&type=game&type=txp&protocol_version=39&engine_version=5.3.0&hide=nonfree&hide=desktop_default>
<https://content.minetest.net/api/packages/?type=tool&type=game&type=asset_pack&protocol_version=39&engine_version=5.3.0&hide=nonfree&hide=desktop_default>
Example response:
@ -33,7 +33,7 @@ Example response:
`thumbnail` is optional, but all other fields are required.
`type` is one of `mod`, `game`, or `txp`.
`type` is one of `tool`, `game`, or `asset_pack`.
`release` is the release ID. Newer releases have higher IDs.
Minetest compares this ID to a locally stored version to detect whether a package has updates.
@ -67,7 +67,7 @@ dependencies for a package.
Then, it resolves each dependency recursively.
Say you're resolving for `basic_materials`, then it will attempt to find the mod in this order:
Say you're resolving for `basic_materials`, then it will attempt to find the tool in this order:
1. It first checks installed mods in the game and mods folder (ie: `mods/basic_materials/`)
2. Then it looks on ContentDB for exact name matches (ie: `VanessaE/basic_materials`)
@ -77,7 +77,7 @@ Say you're resolving for `basic_materials`, then it will attempt to find the mod
### Long version
When installing a package, an API request is made to ContentDB to find out the dependencies.
If there are no dependencies, then the mod is installed straight away.
If there are no dependencies, then the tool is installed straight away.
If there are dependencies, it will resolve them and show a dialog with a list of mods to install.

View File

@ -68,7 +68,7 @@ def upgrade():
sa.Column('title', sa.String(length=100), nullable=False),
sa.Column('shortDesc', sa.String(length=200), nullable=False),
sa.Column('desc', sa.Text(), nullable=True),
sa.Column('type', sa.Enum('MOD', 'GAME', 'TXP', name='packagetype'), nullable=True),
sa.Column('type', sa.Enum('TOOL', 'GAME', 'ASSETPACK', name='packagetype'), nullable=True),
sa.Column('license_id', sa.Integer(), nullable=True),
sa.Column('approved', sa.Boolean(), nullable=False),
sa.Column('repo', sa.String(length=200), nullable=True),

View File

@ -16,7 +16,7 @@ branch_labels = None
depends_on = None
from sqlalchemy.dialects.postgresql import ENUM
type_enum = ENUM('MOD', 'GAME', 'TXP', name='packagetype', create_type=False)
type_enum = ENUM('TOOL', 'GAME', 'ASSETPACK', name='packagetype', create_type=False)
def upgrade():
type_enum.create(op.get_bind(), checkfirst=True)

View File

@ -944,15 +944,15 @@ msgid "Uploaded image isn't actually an image"
msgstr "Hochgeladenes Bild ist nicht wirklich ein Bild"
#: app/models/packages.py:65
msgid "Mod"
msgstr "Mod"
msgid "Tool"
msgstr "Tool"
#: app/models/packages.py:67
msgid "Game"
msgstr "Spiel"
#: app/models/packages.py:69
msgid "Texture Pack"
msgid "Asset Pack"
msgstr "Texturenpaket"
#: app/models/packages.py:74 app/templates/base.html:27

View File

@ -936,15 +936,15 @@ msgid "Uploaded image isn't actually an image"
msgstr "La imagen subida no es realmente una imagen"
#: app/models/packages.py:65
msgid "Mod"
msgstr "Mod"
msgid "Tool"
msgstr "Tool"
#: app/models/packages.py:67
msgid "Game"
msgstr "Juego"
#: app/models/packages.py:69
msgid "Texture Pack"
msgid "Asset Pack"
msgstr "Paquete de texturas"
#: app/models/packages.py:74 app/templates/base.html:27
@ -2394,7 +2394,7 @@ msgstr "Emblemas"
#: app/templates/packages/similar.html:4
msgid "Modname Uniqueness"
msgstr "Originalidad del nombre del mod"
msgstr "Originalidad del nombre del tool"
#: app/templates/packages/similar.html:12
msgid "Packages sharing provided mods"

View File

@ -940,15 +940,15 @@ msgid "Uploaded image isn't actually an image"
msgstr "L'image envoyée n'est pas une image"
#: app/models/packages.py:65
msgid "Mod"
msgstr "Mod"
msgid "Tool"
msgstr "Tool"
#: app/models/packages.py:67
msgid "Game"
msgstr "Jeu"
#: app/models/packages.py:69
msgid "Texture Pack"
msgid "Asset Pack"
msgstr "Pack de texture"
#: app/models/packages.py:74 app/templates/base.html:27
@ -2429,7 +2429,7 @@ msgstr "Badges"
#: app/templates/packages/similar.html:4
msgid "Modname Uniqueness"
msgstr "Originalité du nom du mod"
msgstr "Originalité du nom du tool"
#: app/templates/packages/similar.html:12
msgid "Packages sharing provided mods"

View File

@ -947,7 +947,7 @@ msgid "Uploaded image isn't actually an image"
msgstr ""
#: app/models/packages.py:65
msgid "Mod"
msgid "Tool"
msgstr ""
#: app/models/packages.py:67
@ -956,7 +956,7 @@ msgid "Game"
msgstr "Név"
#: app/models/packages.py:69
msgid "Texture Pack"
msgid "Asset Pack"
msgstr ""
#: app/models/packages.py:74 app/templates/base.html:27

View File

@ -931,7 +931,7 @@ msgid "Uploaded image isn't actually an image"
msgstr ""
#: app/models/packages.py:65
msgid "Mod"
msgid "Tool"
msgstr ""
#: app/models/packages.py:67
@ -941,12 +941,12 @@ msgstr "Nama"
#: app/models/packages.py:69
#, fuzzy
msgid "Texture Pack"
msgid "Asset Pack"
msgstr "Paket Tekstur"
#: app/models/packages.py:74 app/templates/base.html:27
msgid "Mods"
msgstr "Mod"
msgstr "Tool"
#: app/models/packages.py:76 app/templates/base.html:30
msgid "Games"
@ -1185,7 +1185,7 @@ msgstr "Permainan Teratas"
#: app/templates/index.html:124
msgid "Top Mods"
msgstr "Mod Teratas"
msgstr "Tool Teratas"
#: app/templates/index.html:131
msgid "Top Texture Packs"
@ -2408,15 +2408,15 @@ msgstr "Lencana"
#: app/templates/packages/similar.html:4
msgid "Modname Uniqueness"
msgstr "Keunikan Nama Mod"
msgstr "Keunikan Nama Tool"
#: app/templates/packages/similar.html:12
msgid "Packages sharing provided mods"
msgstr "Paket-paket yang turut memakai mod yang diberikan"
msgstr "Paket-paket yang turut memakai tool yang diberikan"
#: app/templates/packages/similar.html:14
msgid "This package contains modnames that are present in the following packages:"
msgstr "Paket ini memiliki nama mod yang ada dalam paket-paket berikut:"
msgstr "Paket ini memiliki nama tool yang ada dalam paket-paket berikut:"
#: app/templates/packages/similar.html:32
msgid "Similar Forum Topics"

View File

@ -904,7 +904,7 @@ msgid "Uploaded image isn't actually an image"
msgstr ""
#: app/models/packages.py:65
msgid "Mod"
msgid "Tool"
msgstr ""
#: app/models/packages.py:67
@ -912,7 +912,7 @@ msgid "Game"
msgstr ""
#: app/models/packages.py:69
msgid "Texture Pack"
msgid "Asset Pack"
msgstr ""
#: app/models/packages.py:74 app/templates/base.html:27

View File

@ -904,7 +904,7 @@ msgid "Uploaded image isn't actually an image"
msgstr ""
#: app/models/packages.py:65
msgid "Mod"
msgid "Tool"
msgstr ""
#: app/models/packages.py:67
@ -912,7 +912,7 @@ msgid "Game"
msgstr ""
#: app/models/packages.py:69
msgid "Texture Pack"
msgid "Asset Pack"
msgstr ""
#: app/models/packages.py:74 app/templates/base.html:27

View File

@ -940,7 +940,7 @@ msgid "Uploaded image isn't actually an image"
msgstr "Imej yang dimuat naik sebenarnya bukan sejenis imej"
#: app/models/packages.py:65
msgid "Mod"
msgid "Tool"
msgstr "Mods"
#: app/models/packages.py:67
@ -948,7 +948,7 @@ msgid "Game"
msgstr "Permainan"
#: app/models/packages.py:69
msgid "Texture Pack"
msgid "Asset Pack"
msgstr "Pek Tekstur"
#: app/models/packages.py:74 app/templates/base.html:27

View File

@ -906,7 +906,7 @@ msgid "Uploaded image isn't actually an image"
msgstr ""
#: app/models/packages.py:65
msgid "Mod"
msgid "Tool"
msgstr ""
#: app/models/packages.py:67
@ -915,7 +915,7 @@ msgid "Game"
msgstr "Navn"
#: app/models/packages.py:69
msgid "Texture Pack"
msgid "Asset Pack"
msgstr ""
#: app/models/packages.py:74 app/templates/base.html:27

View File

@ -933,7 +933,7 @@ msgid "Uploaded image isn't actually an image"
msgstr "Загруженное изображение на самом деле не является изображением"
#: app/models/packages.py:65
msgid "Mod"
msgid "Tool"
msgstr "Мод"
#: app/models/packages.py:67
@ -941,7 +941,7 @@ msgid "Game"
msgstr "Игра"
#: app/models/packages.py:69
msgid "Texture Pack"
msgid "Asset Pack"
msgstr "Пакет текстур"
#: app/models/packages.py:74 app/templates/base.html:27

View File

@ -906,7 +906,7 @@ msgid "Uploaded image isn't actually an image"
msgstr ""
#: app/models/packages.py:65
msgid "Mod"
msgid "Tool"
msgstr ""
#: app/models/packages.py:67
@ -914,7 +914,7 @@ msgid "Game"
msgstr ""
#: app/models/packages.py:69
msgid "Texture Pack"
msgid "Asset Pack"
msgstr ""
#: app/models/packages.py:74 app/templates/base.html:27

View File

@ -910,7 +910,7 @@ msgid "Uploaded image isn't actually an image"
msgstr ""
#: app/models/packages.py:65
msgid "Mod"
msgid "Tool"
msgstr ""
#: app/models/packages.py:67
@ -918,7 +918,7 @@ msgid "Game"
msgstr ""
#: app/models/packages.py:69
msgid "Texture Pack"
msgid "Asset Pack"
msgstr ""
#: app/models/packages.py:74 app/templates/base.html:27

View File

@ -911,8 +911,8 @@ msgid "Uploaded image isn't actually an image"
msgstr ""
#: app/models/packages.py:65
msgid "Mod"
msgstr "Mod"
msgid "Tool"
msgstr "Tool"
#: app/models/packages.py:67
#, fuzzy
@ -921,7 +921,7 @@ msgstr "子游戏"
#: app/models/packages.py:69
#, fuzzy
msgid "Texture Pack"
msgid "Asset Pack"
msgstr "材质包"
#: app/models/packages.py:74 app/templates/base.html:27

View File

@ -909,7 +909,7 @@ msgid "Uploaded image isn't actually an image"
msgstr ""
#: app/models/packages.py:65
msgid "Mod"
msgid "Tool"
msgstr ""
#: app/models/packages.py:67
@ -917,7 +917,7 @@ msgid "Game"
msgstr ""
#: app/models/packages.py:69
msgid "Texture Pack"
msgid "Asset Pack"
msgstr ""
#: app/models/packages.py:74 app/templates/base.html:27