Skip to content
This repository was archived by the owner on Jun 3, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions patchwork-fake-players/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
archivesBaseName = "patchwork-fake-players"
version = getSubprojectVersion(project, "0.1.0")

dependencies {
implementation project(path: ':patchwork-api-base', configuration: 'dev')
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Minecraft Forge, Patchwork Project
* Copyright (c) 2016-2020, 2019-2020
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

package net.minecraftforge.common.util;

import com.mojang.authlib.GameProfile;

import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.packet.c2s.play.ClientSettingsC2SPacket;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.network.ServerPlayerInteractionManager;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.stat.Stat;
import net.minecraft.text.Text;
import net.minecraft.util.math.Vec3d;

// Preliminary, simple Fake Player class
public class FakePlayer extends ServerPlayerEntity {
public FakePlayer(ServerWorld world, GameProfile profile) {
super(world.getServer(), world, profile, new ServerPlayerInteractionManager(world));
}

@Override
public Vec3d getPosVector() {
return new Vec3d(0, 0, 0);
}

@Override
public void addChatMessage(Text text, boolean actionBar) {
}

@Override
public void sendMessage(Text component) {
}

@Override
public void increaseStat(Stat stat, int num) {
}

@Override
public boolean isInvulnerableTo(DamageSource source) {
return true;
}

@Override
public boolean shouldDamagePlayer(PlayerEntity player) {
return false;
}

@Override
public void onDeath(DamageSource source) {
}

@Override
public void tick() {
}

@Override
public void setClientSettings(ClientSettingsC2SPacket packet) {
}

// Forge also has this here:
// @Override @Nullable public MinecraftServer getServer() { return ServerLifecycleHooks.getCurrentServer(); }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Minecraft Forge, Patchwork Project
* Copyright (c) 2016-2020, 2019-2020
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

package net.minecraftforge.common.util;

import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.UUID;

import com.google.common.collect.Maps;
import com.mojang.authlib.GameProfile;

import net.minecraft.server.world.ServerWorld;

public class FakePlayerFactory {
private static final GameProfile MINECRAFT = new GameProfile(UUID.fromString("41C82C87-7AfB-4024-BA57-13D2C99CAE77"), "[Minecraft]");
// Map of all active fake player profiles to their entities
private static final Map<GameProfile, FakePlayer> fakePlayers = Maps.newHashMap();
private static WeakReference<FakePlayer> MINECRAFT_PLAYER = null;

public static FakePlayer getMinecraft(ServerWorld world) {
FakePlayer ret = MINECRAFT_PLAYER != null ? MINECRAFT_PLAYER.get() : null;

if (ret == null) {
ret = FakePlayerFactory.get(world, MINECRAFT);
MINECRAFT_PLAYER = new WeakReference<>(ret);
}

return ret;
}

/**
* Get a fake player with a given profile.
* Mods should either hold weak references to the return value, or listen for a
* WorldEvent.Unload and kill all references to prevent worlds staying in memory.
*/
public static FakePlayer get(ServerWorld world, GameProfile profile) {
return fakePlayers.computeIfAbsent(profile, it -> new FakePlayer(world, it));
}

/**
* Used internally to clean up fake players when worlds are unloaded on server stop.
*/
public static void unloadWorld(ServerWorld world) {
fakePlayers.entrySet().removeIf(entry -> entry.getValue().world == world);

// This shouldn't be strictly necessary, but let's be aggressive.
FakePlayer mc = MINECRAFT_PLAYER != null ? MINECRAFT_PLAYER.get() : null;

if (mc != null && mc.world == world) {
MINECRAFT_PLAYER = null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Minecraft Forge, Patchwork Project
* Copyright (c) 2016-2020, 2019-2020
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

package net.patchworkmc.impl.fakeplayers;

import net.minecraftforge.common.util.FakePlayerFactory;

import net.minecraft.server.world.ServerWorld;

import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.fabricmc.api.ModInitializer;

public class PatchworkFakePlayers implements ModInitializer {
@Override
public void onInitialize() {
ServerLifecycleEvents.SERVER_STOPPED.register(server -> {
for (ServerWorld world : server.getWorlds()) {
FakePlayerFactory.unloadWorld(world);
}
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Minecraft Forge, Patchwork Project
* Copyright (c) 2016-2020, 2019-2020
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

package net.patchworkmc.mixin.fakeplayers;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraftforge.common.util.FakePlayer;

import net.minecraft.advancement.Advancement;
import net.minecraft.advancement.PlayerAdvancementTracker;
import net.minecraft.server.network.ServerPlayerEntity;

@Mixin(PlayerAdvancementTracker.class)
public class MixinPlayerAdvancementTracker {
@Shadow
private ServerPlayerEntity owner;

@Inject(method = "grantCriterion", at = @At("HEAD"), cancellable = true)
private void onGrantCriterion(Advancement advancement, String criterion, CallbackInfoReturnable<Boolean> cir) {
if (owner instanceof FakePlayer) {
cir.setReturnValue(false);
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 29 additions & 0 deletions patchwork-fake-players/src/main/resources/fabric.mod.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"schemaVersion": 1,
"id": "patchwork-fake-players",
"version": "${version}",
"name": "Patchwork Fake Players",
"description": "Implements the Minecraft Forge fake players API",
"authors": [
"PatchworkMC"
],
"license": "LGPL-2.1-only",
"icon": "assets/patchwork-fake-players/icon.png",
"environment": "*",
"depends": {
"patchwork-api-base": "*",
"fabric": "*"
},
"mixins": [
"patchwork-fake-players.mixins.json"
],
"entrypoints": {
"main": [
"net.patchworkmc.impl.fakeplayers.PatchworkFakePlayers"
]
},
"custom": {
"modmenu:api": true,
"modmenu:parent": "patchwork"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"required": true,
"package": "net.patchworkmc.mixin.fakeplayers",
"compatibilityLevel": "JAVA_8",
"mixins": [
"MixinPlayerAdvancementTracker",
],
"injectors": {
"defaultRequire": 1
}
}
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ include 'patchwork-extensions'
include 'patchwork-extensions-block'
include 'patchwork-extensions-item'
include 'patchwork-extensions-shearing'
include 'patchwork-fake-players'
include 'patchwork-fml'
include 'patchwork-god-classes'
include 'patchwork-gui'
Expand Down