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

Server Consent API #3129

Closed
wants to merge 96 commits into from
Closed

Server Consent API #3129

wants to merge 96 commits into from

Conversation

xpple
Copy link
Contributor

@xpple xpple commented Jun 16, 2023

Dear FabricMC development team,

I hereby propose a server consent system for clients. As this is just a proposal, I invite you to share your thoughts on this so that we can come up with something better. Since this system is meant to be universal, I also opened an issue over at Paper for the (server-side) system. The text there is roughly the same, with a few server provider specific exceptions, and of course not including the client-sided aspect specifically for Fabric. Thanks for reading!

Server Consent API

Perhaps a different name would be better.

Summary

This API adds a (universal) server consent system for mods and features
of mods a client connecting to the server uses. The server configures a list
of illegal mods/features and, if enabled, will send the client these lists
when the client connects to the server. Mod developers can then process
this information and if needed disable certain/all functionality. This system
is meant to be standardised across different server software
implementations, so that clients know what to implement.

Goals

  • Standardise a system for client mod developers wanting their mod to be
    used responsibly. This is the main goal!
  • Provide server owners with a system that can ask the client to
    disable some of its mods or some of its mods' functionalities.

Non-Goals

It is absolutely not a goal to provide server owners with a robust
anti-cheat system. This system should not be used in place of anti-cheat
mods and other unfair gameplay preventing plugins/mods. This is not
the intention of this system.

Success Metrics

The amount of client-sided mods that will adopt this system. Though, it
should be noted that this system will not have failed if some mods don't
use this; for servers this system does not have any downsides and any mod
using this is therefore a success.

Motivation

Client mod developers are often powerless to prevent their mods from
being used on servers which do not allow them/do not allow certain of
their functionalities. For instance, many cheat mod developers wouldn't
want their mods to be used outside of anarchy servers, but they have no
way of preventing it. Others might completely dismiss certain features
in fear that they will be used irresponsibly. With this system, client
mod developers are no longer limited in this regard, as they can now
disable their mod/illegal features on servers that want them to.

The server-side implementation as shown by the mod is very minimal,
and server owners only need to change a config to enable this system.
This is beneficial for server owners as it barely requires any effort to
configure. The same applies to the client-side implementation.

Description

This system uses the custom payload channel noconsent:flags to send
the list of mods/features to the client (namespace should be discussed).
The list is a net.minecraft.util.Identifier list with the following design:

  • <mod id>:<feature> requests the feature <feature> of the mod with
    mod id <mod id> to be disabled;
  • c:<feature> requests the feature <feature> of all mods to be disabled;
  • <mod id>:all requests the all the features of the mod with mod id
    <mod id> to be disabled.

The common namespace c is defined by the field
Flags#COMMON_NAMESPACE. The wildcard feature all is defined by
the field Flags#WILDCARD_FEATURE. To aid standardisation, the Flags
class also includes common flags for mod developers to use.

If the server has enabled this system, the server will send the configured
list of mods/features to the client. For now, this list is configured using
JSON. The default config (located at .minecraft/config/fabric/consents.json
is as follows.

{
  "enabled": false,
  "illegalFlags": []
}

An example config might look like this.

{
  "enabled": true,
  "illegalFlags": [
    "c:markers",
    "seedmapper:all"
  ]
}

With this configuration, the server would ask all mods to disable their
markers, and to disable the mod with mod id seedmapper entirely. This
list is parsed by making a simple TypeAdapter<Identifier> provided by
GSON.

When the client receives the list of illegal mods/features, an event will
be triggered by this API to which client mod developers can listen. The
events is ClientFabricServerConsentFlagsCallback.FLAGS_SENT. They can
then check if their mod is included in any way in the list by using the
ClientFabricServerConsent#isIllegal method:

/**
 * Checks for a given flag and mod id whether the flag is illegal.
 *
 * @param flag the flag to check against
 * @return {@code true} if the flag is illegal, {@code false} otherwise
 */
public static boolean isIllegal(Identifier flag) {
	for (Identifier illegalFlag : ClientFabricServerConsentImpl.illegalFlags) {
		if (illegalFlag.getNamespace().equals(Flags.COMMON_NAMESPACE)) {
			if (illegalFlag.getPath().equals(flag.getPath())) {
				return true;
			}
		}

		if (illegalFlag.getNamespace().equals(flag.getNamespace())) {
			if (illegalFlag.getPath().equals(Flags.WILDCARD_FEATURE)) {
				return true;
			}

			if (illegalFlag.getPath().equals(flag.getPath())) {
				return true;
			}
		}
	}

	return false;
}

It is up to the mod developer to decide what to do with this
information.

Alternatives

  • The system is standardised by server software providers, but not
    implemented into them directly. This means that different server
    software providers would agree on a namespace for the list of
    illegal mods/features, but let the configuration and implementation
    be up to server owners to implement. One way this could be
    achieved is by having server software providers document the
    system clearly, with example code for server owners. There are two
    downsides of this approach, though.

    1. The documentation will likely not reach the same audience as
      direct implementation would. That means fewer server owners
      will implement use system, which weakens the system as whole.
    2. It is at the expense of standardisation. Direct implementation
      simply has more of a standardising effect than individual
      standardisation has.
  • This system is not standardised at all. In that case a mod (in the
    case of a Fabric server) could be used by server owners. However,
    there is very little chance a third party mod will be widely adopted
    by servers. Importantly, standardisation is the main goal of this
    system. Without it, disagreement and inconsistency would arise, and
    the system would flop. Only if established server software providers
    choose to adopt this system will this work.

Considering these two alternatives, only the first could actually work.
Third party implementations just don't have the necessary reach to
establish something widespread across the Minecraft developer
community.

@xpple xpple changed the title Foundation for permissions api Foundation for Server Consent API Jun 16, 2023
@xpple
Copy link
Contributor Author

xpple commented Jun 16, 2023

It has become clear that the client sending a list of their mods to the server is a bad idea. I will rewrite the code and PR description accordingly later.

Copy link
Member

@modmuss50 modmuss50 left a comment

Choose a reason for hiding this comment

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

This is going to need a lot of work before its ready, I have left a very high level review based on discussion.

@xpple xpple requested a review from modmuss50 June 28, 2023 18:41
@xpple xpple changed the title Foundation for Server Consent API Server Consent API Jul 14, 2023
@xpple xpple marked this pull request as ready for review July 14, 2023 20:31
modmuss50 and others added 4 commits October 8, 2023 13:02
* Make some experimental APIs stable.

* Imports.
* Implement `LootTableEvents.LOADED` event

* Update for checkstyle

* rename event

* Update fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/api/loot/v2/LootTableEvents.java

Co-authored-by: Juuz <[email protected]>

---------

Co-authored-by: modmuss <[email protected]>
Co-authored-by: Juuz <[email protected]>
(cherry picked from commit 96dfa95)
* Fix inconsistency of placed feature locations

`BiomeSource#getBiomes` mixin applies to all biome sources, including one for Overworld.
The return value is a set; however one caller in the worldgen code iterates over it: `PlacedFeatureIndexer`.
Using a hash set here randomizes the return value, affecting feature placement.
Use a linked hash set instead.

* Improve fix to only make changes when required.

---------

Co-authored-by: modmuss50 <[email protected]>
@AnOpenSauceDev
Copy link

I like the idea of this, but I doubt that this will have a major effect in the end, at least on the side of hacked clients where someone could easily just maintain a fork that ignores the API. After all, most major hacked clients don't even bother to check if the server is anarchy or not. In my opinion it's just too much work for something that probably wont be used often or can easily be bypassed.

@xpple
Copy link
Contributor Author

xpple commented Oct 17, 2023

I like the idea of this, but I doubt that this will have a major effect in the end, at least on the side of hacked clients where someone could easily just maintain a fork that ignores the API. After all, most major hacked clients don't even bother to check if the server is anarchy or not. In my opinion it's just too much work for something that probably wont be used often or can easily be bypassed.

It's up to the developer to adopt this system or not. And yes, it can be easily bypassed. It's an explicit Non-Goal to provide some robust anti-cheat system. This is for client mod developers that want their mod to be used more responsibly.

@gudenau
Copy link

gudenau commented Oct 20, 2023

This would be trivial to bypass as the stated goal is to disabled cheats on servers any "client" could just disable this check. Even mods that use this could have the checks disabled.

@AnOpenSauceDev
Copy link

This would be trivial to bypass as the stated goal is to disabled cheats on servers any "client" could just disable this check. Even mods that use this could have the checks disabled.

I will say, it would totally be possible for someone to make a mod* that consists of a few mixins, that bypasses the check for all mods, which would mean that compliant mod devs would still have their mods misused. It kind of sucks that there isn't a good way to do with without a) being some level of invasive or b) obfuscating code.

*modrinth does not allow these forms of mods, but GitHub and Curseforge could possibly distribute this.

@xpple xpple changed the base branch from 1.20.1 to 1.20.2 October 20, 2023 13:42
# Conflicts:
#	gradle.properties
#	settings.gradle
@xpple xpple changed the base branch from 1.20.2 to 1.20.4 March 6, 2024 18:20
xpple and others added 20 commits March 6, 2024 19:22
* Created tag translation datagen

* generate lang file

* Add fruit translation

* renamed interface injection

* Adjust missing translation message

* Fixed for checkStyle

* More checkstyle fighting...

* Bump version of modules.

* Oops wrong module got bumped

* moving and renaming files

* adjust enum class naming

* rename enum and move package

* Renamed one more enum

* Undo version bump. Will be handled at release

* Some suggestions implemented

* Added crowdin entry

* Update crowdin.yml

Co-authored-by: modmuss <[email protected]>

* Cleanup enum checking

* spotless fixes

* Added buckets and powder snow bucket tag translation

* Some more suggested changes

* setup ConventionLogWarnings to match ConventionLogWarningsClient setup

* Change property to be usable in prod

* Set short as default property

* Remove unused import

* Fixed copy/paste error

* fixed ingot translations

* lang and method name fixes

* Fixed filepath issue

* Fixed redstone name

* fixed javadoc whitespace

* Move translation warning to server

* Move translation class to better file path

* trying to pass the regex

* put it under impl

* Cleanup translation check

* Update fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/api/datagen/v1/provider/FabricLanguageProvider.java

Co-authored-by: Juuz <[email protected]>

* Update fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/api/datagen/v1/provider/FabricLanguageProvider.java

Co-authored-by: haykam821 <[email protected]>

* Update fabric-convention-tags-v2/src/main/java/net/fabricmc/fabric/api/tag/FabricTagKey.java

Co-authored-by: haykam821 <[email protected]>

* Update fabric-convention-tags-v2/src/main/java/net/fabricmc/fabric/api/tag/FabricTagKey.java

Co-authored-by: haykam821 <[email protected]>

---------

Co-authored-by: modmuss <[email protected]>
Co-authored-by: Juuz <[email protected]>
Co-authored-by: haykam821 <[email protected]>
…MC#3726)

* use knownPack to avoid syncing mod data packs.

* remove empty class

* checkstyle and licenses

* move debug logging from testmod into main module

* fix knownPackInfo not working for build-in data packs.

* make bundled data packs not required for client, and don't auto enable

* improve testmod with added builtin data pack + better error message

* Increase max known packs in C2S packet

* validate size before sending
* changeable with system property

* change mixin from ModifyConstant to ModifyArg to be more clear.

* Apply suggestions from code review

Co-authored-by: modmuss <[email protected]>

* store list of knownPacks as server start

avoids desync on pack change (since registries aren't reloaded)

* be extra safe: only request knownPacks that were enabled at server start and still are.

Doesn't rely on the fact that registries aren't synced anymore.

---------

Co-authored-by: modmuss <[email protected]>
* Add API to modify default item components

* Add test for removal

* Some review feedback

* API design changes

* Review feedback

* Add overload that takes a Collection<Item>
- Add all dynamic registries to the initial registry.
 - Expose a getter for the registry future.
 - Register cloners for all dynamic registries.
…C#3749)

* Support loading a single condition instead of array

* Remove extra space

* Use LIST_CODEC field instead of CODEC.listOf()

Co-authored-by: Juuz <[email protected]>

---------

Co-authored-by: Juuz <[email protected]>
* Add resource conditions to dynamic registries

* Support conditions in FabricDynamicRegistryProvider

 - Add matching overloads for all add(...) methods which take a varargs
   list of ResourceConditions.

 - Add an additional overload for registering RegistryEntry.References
   directly. This makes it a little easier to register directly from a
   RegistryBuilder.

* Throw error if we cannot add resource conditions

* Rename EntryWithConditions to ConditionalEntry
- Add exception handling to BlockRenderContext#render to match vanilla
@xpple xpple changed the base branch from 1.20.4 to 1.20.6 May 30, 2024 22:00
xpple added 4 commits May 31, 2024 00:16
…issions-api

# Conflicts:
#	build.gradle
#	crowdin.yml
#	fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/api/attachment/v1/AttachmentTarget.java
#	fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/impl/attachment/AttachmentPersistentState.java
#	fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/impl/attachment/AttachmentSerializingImpl.java
#	fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/impl/attachment/AttachmentTargetImpl.java
#	fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/AttachmentTargetsMixin.java
#	fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/BlockEntityMixin.java
#	fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/ChunkSerializerMixin.java
#	fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/EntityMixin.java
#	fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/ServerWorldMixin.java
#	fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/WrapperProtoChunkMixin.java
#	fabric-data-attachment-api-v1/src/main/resources/fabric-data-attachment-api-v1.mixins.json
#	fabric-data-attachment-api-v1/src/main/resources/fabric.mod.json
#	fabric-data-attachment-api-v1/src/test/java/net/fabricmc/fabric/test/attachment/CommonAttachmentTests.java
#	fabric-data-attachment-api-v1/src/testmod/java/net/fabricmc/fabric/test/attachment/gametest/BlockEntityTests.java
#	fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/api/datagen/v1/provider/FabricCodecDataProvider.java
#	fabric-data-generation-api-v1/src/testmod/java/net/fabricmc/fabric/test/datagen/DataGeneratorTestEntrypoint.java
#	fabric-events-interaction-v0/src/client/java/net/fabricmc/fabric/api/event/client/player/ClientPlayerBlockBreakEvents.java
#	fabric-item-api-v1/src/main/java/net/fabricmc/fabric/api/item/v1/FabricItem.java
#	fabric-item-api-v1/src/main/java/net/fabricmc/fabric/api/item/v1/FabricItemStack.java
#	fabric-item-api-v1/src/main/java/net/fabricmc/fabric/mixin/item/ItemStackMixin.java
#	fabric-item-api-v1/src/main/resources/fabric-item-api-v1.mixins.json
#	fabric-item-api-v1/src/testmod/resources/fabric.mod.json
#	fabric-item-group-api-v1/src/main/resources/assets/fabric/lang/ko_kr.json
#	fabric-lifecycle-events-v1/src/client/java/net/fabricmc/fabric/mixin/event/lifecycle/client/ClientPlayNetworkHandlerMixin.java
#	fabric-networking-api-v1/src/client/java/net/fabricmc/fabric/mixin/networking/client/ClientCommonNetworkHandlerMixin.java
#	fabric-networking-api-v1/src/testmod/java/net/fabricmc/fabric/test/networking/play/NetworkingPlayPacketTest.java
#	fabric-networking-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/networking/client/play/NetworkingPlayPacketClientTest.java
#	fabric-registry-sync-v0/src/main/resources/assets/fabric-registry-sync-v0/lang/de_de.json
#	fabric-registry-sync-v0/src/main/resources/assets/fabric-registry-sync-v0/lang/et_ee.json
#	fabric-registry-sync-v0/src/main/resources/assets/fabric-registry-sync-v0/lang/fr_fr.json
#	fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/CustomAtlasSourcesTest.java
#	fabric-resource-loader-v0/src/client/java/net/fabricmc/fabric/mixin/resource/loader/client/GameOptionsMixin.java
#	fabric-resource-loader-v0/src/client/resources/fabric-resource-loader-v0.client.mixins.json
#	fabric-resource-loader-v0/src/main/java/net/fabricmc/fabric/impl/resource/loader/ModNioResourcePack.java
#	fabric-resource-loader-v0/src/main/java/net/fabricmc/fabric/impl/resource/loader/ModResourcePackCreator.java
#	fabric-resource-loader-v0/src/main/java/net/fabricmc/fabric/impl/resource/loader/ModResourcePackFactory.java
#	fabric-resource-loader-v0/src/main/java/net/fabricmc/fabric/impl/resource/loader/ModResourcePackUtil.java
#	fabric-resource-loader-v0/src/main/java/net/fabricmc/fabric/impl/resource/loader/PlaceholderResourcePack.java
#	fabric-resource-loader-v0/src/main/java/net/fabricmc/fabric/mixin/resource/loader/DatapackCommandMixin.java
#	fabric-resource-loader-v0/src/main/java/net/fabricmc/fabric/mixin/resource/loader/ResourcePackManagerMixin.java
#	fabric-resource-loader-v0/src/main/java/net/fabricmc/fabric/mixin/resource/loader/ResourcePackProfileMixin.java
#	fabric-resource-loader-v0/src/main/resources/assets/fabric-resource-loader-v0/lang/zh_cn.json
#	fabric-resource-loader-v0/src/main/resources/assets/fabric-resource-loader-v0/lang/zh_tw.json
#	fabric-resource-loader-v0/src/test/java/net/fabricmc/fabric/test/resource/loader/unit/ModResourcePackUtilTests.java
#	fabric-resource-loader-v0/src/testmod/java/net/fabricmc/fabric/test/resource/loader/BuiltinResourcePackTestMod.java
#	fabric-transfer-api-v1/src/main/resources/fabric-transfer-api-v1.mixins.json
#	gradle.properties
…sions-api

# Conflicts:
#	deprecated/fabric-convention-tags-v1/src/main/java/net/fabricmc/fabric/impl/tag/convention/ConventionLogWarnings.java
#	fabric-convention-tags-v2/src/datagen/java/net/fabricmc/fabric/impl/tag/convention/datagen/generators/EnglishTagLangGenerator.java
#	fabric-convention-tags-v2/src/generated/resources/assets/fabric-convention-tags-v2/lang/en_us.json
#	fabric-convention-tags-v2/src/main/java/net/fabricmc/fabric/impl/tag/convention/v2/TranslationConventionLogWarnings.java
#	fabric-data-generation-api-v1/src/testmod/java/net/fabricmc/fabric/test/datagen/DataGeneratorTestEntrypoint.java
#	fabric-item-api-v1/src/main/java/net/fabricmc/fabric/api/item/v1/FabricItem.java
#	fabric-item-api-v1/src/main/java/net/fabricmc/fabric/mixin/item/ItemStackMixin.java
#	fabric-item-api-v1/src/testmod/java/net/fabricmc/fabric/test/item/DefaultItemComponentTest.java
#	fabric-resource-loader-v0/src/main/java/net/fabricmc/fabric/impl/resource/loader/ModResourcePackCreator.java
#	fabric-resource-loader-v0/src/main/java/net/fabricmc/fabric/impl/resource/loader/ModResourcePackUtil.java
#	fabric-resource-loader-v0/src/main/java/net/fabricmc/fabric/mixin/resource/loader/SynchronizeRegistriesTaskMixin.java
#	fabric-resource-loader-v0/src/testmod/java/net/fabricmc/fabric/test/mixin/resource/loader/SynchronizeRegistriesTaskMixin.java
#	fabric-screen-handler-api-v1/src/main/java/net/fabricmc/fabric/impl/screenhandler/Networking.java
#	gradle.properties
@xpple xpple changed the base branch from 1.20.6 to 1.21 June 11, 2024 15:28
@xpple xpple closed this Jun 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.