Skip to content

Add optional spawner abuse prevention #15

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
77 changes: 44 additions & 33 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,67 +1,78 @@
buildscript {
repositories {
jcenter()
maven {
name = "forge"
url = "https://files.minecraftforge.net/maven"
url = 'https://maven.minecraftforge.net/'
}
mavenCentral()
}
dependencies {
classpath "net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT"
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true
}
}

apply plugin: "net.minecraftforge.gradle.forge"
apply plugin: 'net.minecraftforge.gradle'



version = modVersion
group = modGroup
archivesBaseName = modBaseName

sourceCompatibility = targetCompatibility = '1.8'


minecraft {
version = project.forgeVersion
runDir = "run"

// the mappings can be changed at any time, and must be in the following format.
// snapshot_YYYYMMDD snapshot are built nightly.
// stable_# stables are built at the discretion of the MCP team.
// Use non-default mappings at your own risk. they may not always work.
// simply re-run your setup task after changing the mappings to update your workspace.
mappings = project.mcpVersion
replace "@VERSION@", project.version
mappings channel: mappings_channel, version: mappings_version

runs {
client {
args "--username=InDev"

jvmArg "-Dmixin.hotSwap=true"
jvmArg "-Dmixin.checks.interfaces=true"

workingDirectory project.file('run')

property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
property 'forge.logging.console.level', 'debug'
}

server {

jvmArg "-Dmixin.hotSwap=true"
jvmArg "-Dmixin.checks.interfaces=true"

workingDirectory project.file('run')

property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
property 'forge.logging.console.level', 'debug'
}
}
}

repositories {
mavenCentral()
}

dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
testCompile "org.mockito:mockito-core:2.+"
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
testImplementation('junit:junit:4.13')
testImplementation("org.mockito:mockito-core:+")
}

processResources {
// this will ensure that this task is redone when the versions change.
inputs.property "modVersion", project.version
inputs.property "mcVersion", project.minecraft.version

// replace stuff in mcmod.info, nothing else
from(sourceSets.main.resources.srcDirs) {
include "mcmod.info"

// replace version and mcversion
expand "modVersion": project.version, "mcVersion": project.minecraft.version
}
processResources {
inputs.property "version", project.version
inputs.property "mcversion", minecraft_version

// copy everything else, thats not the mcmod.info
from(sourceSets.main.resources.srcDirs) {
exclude "mcmod.info"
filesMatching('mcmod.info') {
expand 'mod_id': modBaseName, 'mod_name': modBaseName, 'version': project.version,
'mcversion': minecraft_version, 'mod_description': mod_description,
'mod_author': modGroup
}

rename '(.+_at.cfg)', 'META-INF/$1'
}


jar {
manifest {
attributes 'FMLAT': 'spawnercontrol_at.cfg'
Expand Down
13 changes: 8 additions & 5 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
modGroup=Ladysnake
modVersion=1.6.3b
modVersion=1.7.0
modBaseName=SpawnerControl
#forgeVersion=1.11.2-13.20.1.2579
#mcpVersion=stable_32
forgeVersion=1.12.2-14.23.3.2669
mcpVersion=snapshot_20180104
mcpVersion=snapshot_20180104
mod_description=A minecraft mod to control mob spawner behaviour

minecraft_version=1.12.2
forge_version=14.23.5.2860
mappings_channel=stable
mappings_version=39-1.12
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Thu Jan 04 15:07:18 CET 2018
#Sun Oct 06 12:09:16 CEST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
5 changes: 3 additions & 2 deletions src/main/java/ladysnake/spawnercontrol/SpawnerControl.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.common.capabilities.CapabilityManager;
Expand Down Expand Up @@ -57,12 +58,12 @@ public void preInit(FMLPreInitializationEvent event) {
CapabilityManager.INSTANCE.register(IControllableSpawner.class, new CapabilityControllableSpawner.Storage(), CapabilityControllableSpawner.DefaultControllableSpawner::new);
// No need to register a tile entity that's not used anywhere
if (MSCConfig.customSpawners.length > 0)
GameRegistry.registerTileEntity(TileEntityControlledSpawner.class, "spawnercontrol:controlled_spawner");
GameRegistry.registerTileEntity(TileEntityControlledSpawner.class,new ResourceLocation("spawnercontrol:controlled_spawner"));
if (MSCConfig.makeCreativeTab) {
creativeTab = new CreativeTabs(MOD_ID) {
@Nonnull
@Override
public ItemStack getTabIconItem() {
public ItemStack createIcon() {
return new ItemStack(Blocks.MOB_SPAWNER);
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import ladysnake.spawnercontrol.controlledspawner.TileEntityControlledSpawner;
import net.minecraft.block.Block;
import net.minecraft.block.BlockMobSpawner;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
Expand Down Expand Up @@ -142,10 +143,12 @@ public static void onCheckSpawnerSpawn(LivingSpawnEvent.CheckSpawn event) {
}
// increments spawn counts and prevents spawns if over the limit
if (canSpawn) {
if (handler.canSpawn()) {
if (handler.canSpawn() && !handler.tooManyAlive()) {
if (!handler.getConfig().incrementOnMobDeath)
handler.incrementSpawnedMobsCount();

handler.incrementAliveMobsCount();

NBTTagCompound compound = new NBTTagCompound();
World spawnerWorld = spawner.getSpawnerWorld();
// When unit testing, the world will be null
Expand Down Expand Up @@ -196,6 +199,7 @@ public static void onLivingDeath(LivingDeathEvent event) {
IControllableSpawner handler = CapabilityControllableSpawner.getHandler(spawner);
if (handler.getConfig().incrementOnMobDeath)
handler.incrementSpawnedMobsCount();
handler.decrementAliveMobsCount();
}
}
}
Expand Down Expand Up @@ -233,7 +237,7 @@ public static void onLivingItemDrop(LivingDropsEvent event) {
ItemStack stack = drop.getItem();
for (String s : entry.removedItems) {
String[] split = s.split(":");
if (stack.getUnlocalizedName().equals(split[0] + ":" + split[1])
if (stack.getTranslationKey().equals(split[0] + ":" + split[1])
&& (split.length < 3 || stack.getMetadata() == Integer.parseInt(split[2]))) {
drops.remove(drop);
}
Expand Down
12 changes: 9 additions & 3 deletions src/main/java/ladysnake/spawnercontrol/config/SpawnerConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ public class SpawnerConfig {
@Config.Comment("When a spawner has spawned this number of mobs over this lifetime, it will get broken automatically")
public int mobThreshold = 100;

@Config.Comment("While this number of mobs from this spawner are alive, it will pause spawning")
public int aliveMobThreshold = 100;

@Config.Comment("Pause spawning if too many spawned mobs are alive")
public boolean pauseIfTooManyAlive = false;

@Config.Comment("If set to true, spawners will count mobs when they are killed rather than when they are spawned")
public boolean incrementOnMobDeath = false;

Expand Down Expand Up @@ -75,7 +81,7 @@ public static class MobLoot {
List<String> addedItems = Arrays.asList(defaultValues.addedItems);
for (String s : xpMultipliers) {
String[] split = s.split(":");
if (split[0].equals(rl.getResourcePath()) && split[1].equals(rl.getResourceDomain())) {
if (split[0].equals(rl.getPath()) && split[1].equals(rl.getNamespace())) {
try {
xpMultiplier = Float.parseFloat(split[2]);
flatXpIncrease = split.length > 3 ? Integer.parseInt(split[3]) : defaultValues.flatXpIncrease;
Expand All @@ -88,7 +94,7 @@ public static class MobLoot {
for (String s : itemDropRemovals) {
String[] split = s.split(",");
String[] mobSplit = split[0].split(":");
if (mobSplit[0].equals(rl.getResourcePath()) && mobSplit[1].equals(rl.getResourceDomain())) {
if (mobSplit[0].equals(rl.getPath()) && mobSplit[1].equals(rl.getNamespace())) {
try {
removedItems = Arrays.asList(split);
removedItems.remove(0);
Expand All @@ -101,7 +107,7 @@ public static class MobLoot {
}
for (String s : itemDropAdditions) {
String[] split = s.split(":");
if (split[0].equals(rl.getResourcePath()) && split[1].equals(rl.getResourceDomain())) {
if (split[0].equals(rl.getPath()) && split[1].equals(rl.getNamespace())) {
try {
addedItems = Arrays.asList(split);
addedItems.remove(0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public void sync() {
public Block createBlock() {
return new BlockControlledSpawner(getConfigObject())
.setRegistryName(this.registryName)
.setUnlocalizedName("msc." + name)
.setTranslationKey("msc." + name)
.setCreativeTab(SpawnerControl.creativeTab);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityInject;
import net.minecraftforge.common.capabilities.ICapabilitySerializable;
import net.minecraftforge.common.util.Constants;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
Expand All @@ -30,6 +31,7 @@ public static IControllableSpawner getHandler(TileEntityMobSpawner entity) {
public static class DefaultControllableSpawner implements IControllableSpawner {
private final TileEntityMobSpawner spawner;
private int spawnedMobsCount;
private int aliveMobsCount;

public DefaultControllableSpawner() {
this(null);
Expand All @@ -44,6 +46,11 @@ public void setSpawnedMobsCount(int mobCount) {
this.spawnedMobsCount = mobCount;
}

@Override
public void setAliveMobsCount(int mobCount) {
this.aliveMobsCount = mobCount;
}

@Override
public boolean incrementSpawnedMobsCount() {
SpawnerConfig cfg = getConfig();
Expand All @@ -56,24 +63,58 @@ public boolean incrementSpawnedMobsCount() {
return false;
}

@Override
public void incrementAliveMobsCount() {
++aliveMobsCount;
}

@Override
public void decrementAliveMobsCount() {
--aliveMobsCount;
}

/**
* Should be called after every spawn to tweak the cooldown according to the config
*/
protected void adjustDelayAfterSpawn(MobSpawnerBaseLogic spawnerBaseLogic, double spawnRateModifier) {
spawnerBaseLogic.minSpawnDelay *= spawnRateModifier;
spawnerBaseLogic.maxSpawnDelay *= spawnRateModifier;
NBTTagCompound tags = new NBTTagCompound();
spawnerBaseLogic.writeToNBT(tags);
int minSpawnDelay = tags.getInteger("MinSpawnDelay");
int maxSpawnDelay = tags.getInteger("MaxSpawnDelay");

minSpawnDelay = (int) (minSpawnDelay*spawnRateModifier);
maxSpawnDelay = (int) (maxSpawnDelay*spawnRateModifier);

tags.setInteger("MinSpawnDelay",minSpawnDelay);
tags.setInteger("MaxSpawnDelay",maxSpawnDelay);

spawnerBaseLogic.readFromNBT(tags);

}

@Override
public int getSpawnedMobsCount() {
return spawnedMobsCount;
}

@Override
public int getAliveMobsCount() {
return aliveMobsCount;
}

@Override
public boolean canSpawn() {
return this.spawnedMobsCount < getConfig().mobThreshold;
}

@Override
public boolean tooManyAlive() {
if(getConfig().pauseIfTooManyAlive)
return this.aliveMobsCount >= getConfig().aliveMobThreshold;
else
return false;
}

@Nonnull
@Override
public SpawnerConfig getConfig() {
Expand Down Expand Up @@ -117,13 +158,15 @@ public static class Storage implements Capability.IStorage<IControllableSpawner>
public NBTBase writeNBT(Capability<IControllableSpawner> capability, IControllableSpawner instance, EnumFacing side) {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setInteger("SpawnedMobsCount", instance.getSpawnedMobsCount());
nbt.setInteger("AliveMobsCount", instance.getAliveMobsCount());
return nbt;
}

@Override
public void readNBT(Capability<IControllableSpawner> capability, IControllableSpawner instance, EnumFacing side, NBTBase nbt) {
if (nbt instanceof NBTTagCompound) {
instance.setSpawnedMobsCount(((NBTTagCompound) nbt).getInteger("SpawnedMobsCount"));
instance.setAliveMobsCount(((NBTTagCompound) nbt).getInteger("AliveMobsCount"));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ public interface IControllableSpawner {
int getSpawnedMobsCount();

boolean canSpawn();
boolean tooManyAlive();

SpawnerConfig getConfig();

void incrementAliveMobsCount();
void decrementAliveMobsCount();
void setAliveMobsCount(int var1);
int getAliveMobsCount();
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public ItemBlockControlSpawner(Block block, String name) {
@Override
public String getItemStackDisplayName(@Nonnull ItemStack stack) {
// in case someone makes a custom lang file to translate their spawner names
if (I18n.canTranslate(getUnlocalizedName(stack) + ".name"))
if (I18n.canTranslate(getTranslationKey(stack) + ".name"))
return super.getItemStackDisplayName(stack);
// return a default readable value
return I18n.translateToLocalFormatted(DEFAULT_LANG_KEY, name).trim();
Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/mcmod.info
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
"modid": "spawnercontrol",
"name": "SpawnerControl",
"description": "A mod to customise spawners behaviour",
"version": "${modVersion}",
"mcversion": "${mcVersion}",
"version": "${version}",
"mcversion": "${mcversion}",
"url": "",
"updateUrl": "",
"authorList": [
Expand Down