Skip to content

Commit

Permalink
Migrate Offline-Player-Cache & Integrate into main mod
Browse files Browse the repository at this point in the history
  • Loading branch information
bibi-reden committed Feb 18, 2024
1 parent 8ff53fb commit 6ecc6bf
Show file tree
Hide file tree
Showing 33 changed files with 853 additions and 78 deletions.
12 changes: 11 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ repositories {
name = "Ladysnake Mods"
url = 'https://maven.ladysnake.org/releases'
}
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}

loom {
Expand Down Expand Up @@ -44,13 +48,19 @@ dependencies {
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
modImplementation "net.fabricmc:fabric-language-kotlin:${project.fabric_kotlin_version}"

// Replace modImplementation with modApi if you expose components in your own API *
// Cardinal Components
modImplementation "dev.onyxstudios.cardinal-components-api:cardinal-components-base:${project.cardinal_components_version}"
include "dev.onyxstudios.cardinal-components-api:cardinal-components-base:${project.cardinal_components_version}"
modImplementation "dev.onyxstudios.cardinal-components-api:cardinal-components-entity:${project.cardinal_components_version}"
include "dev.onyxstudios.cardinal-components-api:cardinal-components-entity:${project.cardinal_components_version}"
modImplementation "dev.onyxstudios.cardinal-components-api:cardinal-components-chunk:${project.cardinal_components_version}"
include "dev.onyxstudios.cardinal-components-api:cardinal-components-chunk:${project.cardinal_components_version}"
modImplementation "dev.onyxstudios.cardinal-components-api:cardinal-components-level:${project.cardinal_components_version}"
include "dev.onyxstudios.cardinal-components-api:cardinal-components-level:${project.cardinal_components_version}"

modImplementation "maven.modrinth:projectile-damage-attribute:${project.projectile_damage_attribute_version}-fabric"

modImplementation include("maven.modrinth:AdditionalEntityAttributes:${project.additional_entity_attributes_version}")
}

processResources {
Expand Down
4 changes: 3 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ archives_base_name=playerex-directors-cut

# Dependencies
fabric_version=0.92.0+1.20.1
cardinal_components_version=5.2.2
cardinal_components_version=5.2.2
additional_entity_attributes_version=1.7.0+1.20.0
projectile_damage_attribute_version=3.2.2+1.20.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.edelweiss.playerex.mixin;

import com.edelweiss.playerex.cache.PlayerEXCacheData;
import com.edelweiss.playerex.cache.PlayerEXCacheInternal;
import com.mojang.datafixers.DataFixer;
import com.mojang.serialization.Dynamic;
import com.mojang.serialization.Lifecycle;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement;
import net.minecraft.nbt.NbtList;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.world.gen.GeneratorOptions;
import net.minecraft.world.level.LevelInfo;
import net.minecraft.world.level.LevelProperties;
import net.minecraft.world.level.storage.SaveVersionInfo;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

@Mixin(LevelProperties.class)
abstract class LevelPropertiesMixin implements PlayerEXCacheData {
@Unique
private final PlayerEXCacheInternal playerEXCache = new PlayerEXCacheInternal();

@Inject(method = "updateProperties", at = @At("HEAD"))
private void playerex_updateProperties(DynamicRegistryManager registryManager, NbtCompound levelNbt, NbtCompound playerNbt, CallbackInfo ci) {
levelNbt.put("PlayerEXCache", playerEXCache.writeToNbt());
}

@Inject(method = "readProperties", at = @At("RETURN"))
private static void playerex_readProperties(Dynamic<NbtElement> dynamic, DataFixer dataFixer, int dataVersion, NbtCompound playerData, LevelInfo levelInfo, SaveVersionInfo saveVersionInfo, LevelProperties.SpecialProperty specialProperty, GeneratorOptions generatorOptions, Lifecycle lifecycle, CallbackInfoReturnable<LevelProperties> cir) {
LevelProperties levelProperties = cir.getReturnValue();
dynamic.get("PlayerEXCache").result().map(Dynamic::getValue).ifPresent(nbtElement -> ((PlayerEXCacheData) levelProperties).playerEXCache().readFromNbt((NbtList) nbtElement));
}

@Override
public PlayerEXCacheInternal playerEXCache() {
return this.playerEXCache;
}
}
51 changes: 51 additions & 0 deletions src/main/java/com/edelweiss/playerex/mixin/PlayerManagerMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.edelweiss.playerex.mixin;

import com.edelweiss.playerex.cache.PlayerEXCacheInternal;
import net.minecraft.network.ClientConnection;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.PlayerManager;
import net.minecraft.server.network.ServerPlayerEntity;
import org.spongepowered.asm.mixin.Final;
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.CallbackInfo;

import java.util.List;

@Mixin(PlayerManager.class)
abstract class PlayerManagerMixin {

@Final
@Shadow
private MinecraftServer server;

@Final
@Shadow
private List<ServerPlayerEntity> players;

@Inject(method = "onPlayerConnect", at = @At("TAIL"))
private void playerex_onPlayerConnect(ClientConnection connection, ServerPlayerEntity player, CallbackInfo ci) {
PlayerEXCacheInternal.Companion.ifCachePresent(this.server, null, playerCache -> {
playerCache.uncache(player);
return null;
});
}

@Inject(method = "remove", at = @At("HEAD"))
private void playerex_remove(ServerPlayerEntity player, CallbackInfo ci) {
PlayerEXCacheInternal.Companion.ifCachePresent(this.server, null, playerCache -> {
playerCache.cache(player);
return null;
});
}

@Inject(method = "disconnectAllPlayers", at = @At("HEAD"))
private void playerex_disconnectAllPlayers(CallbackInfo ci) {
PlayerEXCacheInternal.Companion.ifCachePresent(this.server, null, playerCache -> {
for (ServerPlayerEntity player : this.players) { playerCache.cache(player); }
return null;
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.edelweiss.playerex.mixin;

import com.edelweiss.playerex.cache.PlayerEXCacheData;
import com.edelweiss.playerex.cache.PlayerEXCacheInternal;
import net.minecraft.world.level.ServerWorldProperties;
import net.minecraft.world.level.UnmodifiableLevelProperties;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;

@Mixin(UnmodifiableLevelProperties.class)
abstract class UnmodifiableLevelPropertiesMixin implements PlayerEXCacheData {
@Final
@Shadow
private ServerWorldProperties worldProperties;

@NotNull
@Override
public PlayerEXCacheInternal playerEXCache() {
return ((PlayerEXCacheData) this.worldProperties).playerEXCache();
}
}
34 changes: 34 additions & 0 deletions src/main/kotlin/com/edelweiss/playerex/PlayerEXComponents.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.edelweiss.playerex

import com.edelweiss.playerex.api.PlayerEXAPI
import com.edelweiss.playerex.components.LivingEntityComponent
import com.edelweiss.playerex.components.PlayerEntityComponent
import dev.onyxstudios.cca.api.v3.component.ComponentKey
import dev.onyxstudios.cca.api.v3.component.ComponentRegistry
import dev.onyxstudios.cca.api.v3.entity.EntityComponentFactoryRegistry
import dev.onyxstudios.cca.api.v3.entity.EntityComponentInitializer
import dev.onyxstudios.cca.api.v3.level.LevelComponentFactoryRegistry
import dev.onyxstudios.cca.api.v3.level.LevelComponentInitializer
import dev.onyxstudios.cca.api.v3.world.WorldComponentFactoryRegistry
import dev.onyxstudios.cca.api.v3.world.WorldComponentInitializer
import net.minecraft.entity.LivingEntity

class PlayerEXComponents : EntityComponentInitializer, LevelComponentInitializer, WorldComponentInitializer {
companion object {
val livingEntities: ComponentKey<LivingEntityComponent> = ComponentRegistry.getOrCreate(PlayerEXAPI.id("living_entities"), LivingEntityComponent::class.java)
val playerEntities: ComponentKey<PlayerEntityComponent> = ComponentRegistry.getOrCreate(PlayerEXAPI.id("player_entities"), PlayerEntityComponent::class.java)
}

override fun registerEntityComponentFactories(registry: EntityComponentFactoryRegistry) {
registry.registerFor(LivingEntity::class.java, livingEntities) { entity -> LivingEntityComponent(entity) }
registry.registerForPlayers(playerEntities) { player -> PlayerEntityComponent(player) }
}

override fun registerLevelComponentFactories(registry: LevelComponentFactoryRegistry) {

}

override fun registerWorldComponentFactories(registry: WorldComponentFactoryRegistry) {

}
}

This file was deleted.

38 changes: 38 additions & 0 deletions src/main/kotlin/com/edelweiss/playerex/PlayerEXDirectorsCut.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.edelweiss.playerex

import com.edelweiss.playerex.commands.PlayerEXCacheCommands
import com.edelweiss.playerex.commands.PlayerEXCommands
import net.fabricmc.api.ModInitializer
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback
import org.slf4j.LoggerFactory

object PlayerEXDirectorsCut : ModInitializer {
const val MODID: String = "playerex"

val logger = LoggerFactory.getLogger(MODID)

private fun registerCommands() = CommandRegistrationCallback.EVENT.register { dispatcher, _, _ ->
val head = PlayerEXCommands.registerHead(dispatcher)
PlayerEXCacheCommands.register(head)
}

override fun onInitialize() {
// ServerLifecycleEvents.SERVER_STARTING.register(ServerEventListeners::serverStarting)
// ServerPlayerEvents.COPY_FROM.register(ServerEventListeners::reset)

// // Register LivingEntity events
// LivingEntityEvents.ON_HEAL.register(EventFactory::healed);
// LivingEntityEvents.EVERY_SECOND.register(EventFactory::healthRegeneration);
// LivingEntityEvents.ON_DAMAGE.register(EventFactory::onDamage);
// LivingEntityEvents.SHOULD_DAMAGE.register(EventFactory::shouldDamage);
//
// // Register PlayerEntity events
// PlayerEntityEvents.ON_CRIT.register(EventFactory::onCritAttack);
// PlayerEntityEvents.SHOULD_CRIT.register(EventFactory::attackIsCrit);
//
// // Register attribute modification events
// EntityAttributeModifiedEvents.CLAMPED.register(EventFactory::clamped);

this.registerCommands()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator

object PlayerEXDirectorsCutDataGenerator : DataGeneratorEntrypoint {
override fun onInitializeDataGenerator(fabricDataGenerator: FabricDataGenerator) {

}
}
18 changes: 0 additions & 18 deletions src/main/kotlin/com/edelweiss/playerex/Playerexdirectorscut.kt

This file was deleted.

17 changes: 17 additions & 0 deletions src/main/kotlin/com/edelweiss/playerex/api/PlayerEXAPI.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.edelweiss.playerex.api

import com.edelweiss.playerex.PlayerEXDirectorsCut
import com.edelweiss.playerex.cache.PlayerEXCache
import com.edelweiss.playerex.values.LevelValue
import net.minecraft.util.Identifier

/** Singleton used for main API access for PlayerEX. */
object PlayerEXAPI {
val LEVEL_VALUE = PlayerEXCache.register(LevelValue())


/**
* Creates and returns an `Identifier` based on the PlayerEX mod id.
* */
fun id(str: String) = Identifier(PlayerEXDirectorsCut.MODID, str)
}
8 changes: 0 additions & 8 deletions src/main/kotlin/com/edelweiss/playerex/api/PlayerEXDCApi.kt

This file was deleted.

21 changes: 21 additions & 0 deletions src/main/kotlin/com/edelweiss/playerex/cache/CachedPlayerValue.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.edelweiss.playerex.cache

import net.minecraft.nbt.NbtCompound
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier

interface CachedPlayerValue<V> {
/**
* Used to get the cached value from the player.
* */
fun get(player: ServerPlayerEntity): V

/** Reads a value from a nbt. */
fun readFromNbt(tag: NbtCompound): V

/** Writes a value to a nbt. */
fun writeToNbt(tag: NbtCompound, value: Any?): Boolean

/** The key of the value. This would be used in the form `modid:<path>`. */
fun id(): Identifier
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.edelweiss.playerex.cache

enum class PlayerCacheKeys(val key: String) {
UUID("uuid"),
Name("name"),
Keys("keys"),
}
40 changes: 40 additions & 0 deletions src/main/kotlin/com/edelweiss/playerex/cache/PlayerEXCache.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.edelweiss.playerex.cache

import com.edelweiss.playerex.PlayerEXDirectorsCut
import net.minecraft.server.MinecraftServer
import java.util.UUID

interface PlayerEXCache {
companion object {
/** Registers the provided cached value to the server. */
fun <V>register(key: CachedPlayerValue<V>): CachedPlayerValue<V> {
PlayerEXDirectorsCut.logger.debug("Cached Value has been registered: <{} :: #id: {}>", key, key.id())
return PlayerEXCacheInternal.register(key)
}

/** Get access to the cache object. Should only be used on the server. */
fun <T>getCache(server: MinecraftServer, fallback: T, function: (PlayerEXCache) -> T): T {
val provider = PlayerEXCacheProvider(server)
if (provider.isEmpty()) return fallback
return function(provider)
}
}

/** Fetches the last cached value if offline, otherwise will fetch the current value from the player. */
fun <V>get(uuid: UUID, key: CachedPlayerValue<V>) {}

/** Fetches the last cached value if offline, otherwise will fetch the current value from the player. */
fun <V>get(playerName: String, key: CachedPlayerValue<V>) {}

/** Returns all offline & online player UUIDs. */
fun playerIDs(): Set<UUID>

/** Returns all offline & online player names. */
fun playerNames(): Set<String>

/** Checks if the player with the UUID is in the cache or not. */
fun isPlayerCached(uuid: UUID): Boolean

/** Checks if the player with the name is in the cache or not. */
fun isPlayerCached(playerName: String)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.edelweiss.playerex.cache

interface PlayerEXCacheData {
fun playerEXCache(): PlayerEXCacheInternal
}
Loading

0 comments on commit 6ecc6bf

Please sign in to comment.