Skip to content

Commit

Permalink
Update gamerule handling
Browse files Browse the repository at this point in the history
* Fixes commandModificationBlockLimit value type
* Updates from deprecated Spigot methods
* Updates gamerule value conversion
  • Loading branch information
PseudoKnight committed Dec 4, 2024
1 parent 490e3d8 commit 45eddad
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 19 deletions.
4 changes: 2 additions & 2 deletions src/main/java/com/laytonsmith/abstraction/MCWorld.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ public interface MCWorld extends MCMetadatable {

String[] getGameRules();

String getGameRuleValue(String gameRule);
Object getGameRuleValue(MCGameRule gameRule);

boolean setGameRuleValue(MCGameRule gameRule, String value);
boolean setGameRuleValue(MCGameRule gameRule, Object value);

MCWorldBorder getWorldBorder();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import org.bukkit.Chunk;
import org.bukkit.Effect;
import org.bukkit.FireworkEffect;
import org.bukkit.GameRule;
import org.bukkit.HeightMap;
import org.bukkit.Location;
import org.bukkit.Particle;
Expand Down Expand Up @@ -181,13 +182,21 @@ public String[] getGameRules() {
}

@Override
public String getGameRuleValue(String gameRule) {
return w.getGameRuleValue(gameRule);
public Object getGameRuleValue(MCGameRule gameRule) {
GameRule gr = GameRule.getByName(gameRule.getRuleName());
if(gr == null) {
return null;
}
return w.getGameRuleValue(gr);
}

@Override
public boolean setGameRuleValue(MCGameRule gameRule, String value) {
return w.setGameRuleValue(gameRule.getRuleName(), value);
public boolean setGameRuleValue(MCGameRule gameRule, Object value) {
GameRule gr = GameRule.getByName(gameRule.getRuleName());
if(gr == null) {
return false;
}
return w.setGameRule(gr, value);
}

@Override
Expand Down
30 changes: 27 additions & 3 deletions src/main/java/com/laytonsmith/abstraction/enums/MCGameRule.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
package com.laytonsmith.abstraction.enums;

import com.laytonsmith.annotations.MEnum;
import com.laytonsmith.core.ArgumentValidation;
import com.laytonsmith.core.MSLog;
import com.laytonsmith.core.constructs.CBoolean;
import com.laytonsmith.core.constructs.CInt;
import com.laytonsmith.core.constructs.CString;
import com.laytonsmith.core.constructs.Target;
import com.laytonsmith.core.natives.interfaces.Mixed;

@MEnum("com.commandhelper.GameRule")
public enum MCGameRule {
ANNOUNCEADVANCEMENTS("announceAdvancements"),
BLOCKEXPLOSIONDROPDECAY("blockExplosionDropDecay"),
COMMANDBLOCKOUTPUT("commandBlockOutput"),
COMMANDMODIFICATIONBLOCKLIMIT("commandModificationBlockLimit"),
COMMANDMODIFICATIONBLOCKLIMIT("commandModificationBlockLimit", CInt.class),
DISABLEELYTRAMOVEMENTCHECK("disableElytraMovementCheck"),
DISABLEPLAYERMOVEMENTCHECK("disablePlayerMovementCheck"),
DISABLERAIDS("disableRaids"),
Expand Down Expand Up @@ -87,7 +91,27 @@ public String getRuleName() {
return this.gameRule;
}

public Class<? extends Mixed> getRuleType() {
return this.ruleType;
public Object convertValue(Mixed value, Target t) {
if(this.ruleType == CBoolean.class) {
return ArgumentValidation.getBooleanish(value, t);
} else if(this.ruleType == CInt.class) {
return ArgumentValidation.getInt(value, t);
}
MSLog.GetLogger().e(MSLog.Tags.RUNTIME, "The gamerule \"" + this.gameRule + "\""
+ " has an invalid type.", t);
return null;
}

public Mixed constructValue(Object value, Target t) {
try {
if(this.ruleType == CBoolean.class) {
return CBoolean.get((Boolean) value);
} else if(this.ruleType == CInt.class) {
return new CInt((Integer) value, t);
}
} catch(ClassCastException ex) {}
MSLog.GetLogger().e(MSLog.Tags.RUNTIME, "The gamerule \"" + this.gameRule + "\""
+ " has an invalid type.", t);
return new CString(value.toString(), t);
}
}
29 changes: 19 additions & 10 deletions src/main/java/com/laytonsmith/core/functions/World.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.laytonsmith.annotations.api;
import com.laytonsmith.annotations.hide;
import com.laytonsmith.core.ArgumentValidation;
import com.laytonsmith.core.MSLog;
import com.laytonsmith.core.MSVersion;
import com.laytonsmith.core.ObjectGenerator;
import com.laytonsmith.core.Optimizable;
Expand Down Expand Up @@ -1811,20 +1812,25 @@ public Mixed exec(Target t, Environment environment, Mixed... args) throws Confi
}
if(args.length == 1) {
CArray gameRules = CArray.GetAssociativeArray(t);
for(String gameRule : world.getGameRules()) {
gameRules.set(new CString(gameRule, t),
Static.resolveConstruct(world.getGameRuleValue(gameRule), t), t);
for(String name : world.getGameRules()) {
try {
MCGameRule gameRule = MCGameRule.valueOf(name.toUpperCase());
gameRules.set(name, gameRule.constructValue(world.getGameRuleValue(gameRule), t), t);
} catch(IllegalArgumentException skip) {
MSLog.GetLogger().w(MSLog.Tags.RUNTIME, "The server gamerule \"" + name + "\""
+ " is missing in CommandHelper.", t);
}
}
return gameRules;
} else {
try {
MCGameRule gameRule = MCGameRule.valueOf(args[1].val().toUpperCase());
String value = world.getGameRuleValue(gameRule.getRuleName());
if(value.isEmpty()) {
Object value = world.getGameRuleValue(gameRule);
if(value == null) {
throw new CREFormatException("The gamerule \"" + args[1].val()
+ "\" does not exist in this version.", t);
}
return Static.resolveConstruct(value, t);
return gameRule.constructValue(value, t);
} catch (IllegalArgumentException exception) {
throw new CREFormatException("The gamerule \"" + args[1].val() + "\" does not exist.", t);
}
Expand Down Expand Up @@ -1862,9 +1868,9 @@ public Boolean runAsync() {

@Override
public String docs() {
return "boolean {[world], gameRule, value} Sets the value of the gamerule for the specified world. If world is"
+ " not given the value is set for all worlds. Returns true if successful. The gameRule can be "
+ StringUtils.Join(MCGameRule.getGameRules(), ", ", ", or ", " or ") + ".";
return "boolean {[world], gameRule, value} Sets the value of the gamerule for the specified world."
+ " If world is not given the value is set for all worlds. Returns true if successful."
+ " The gameRule can be " + StringUtils.Join(MCGameRule.getGameRules(), ", ", ", or ", " or ") + ".";
}

@Override
Expand All @@ -1883,7 +1889,10 @@ public Mixed exec(Target t, Environment environment, Mixed... args) throws Confi
throw new CREFormatException("The gamerule \"" + (args.length == 2 ? args[0].val() : args[1].val())
+ "\" does not exist.", t);
}
String value = ArgumentValidation.getObject(args[offset + 1], t, gameRule.getRuleType()).val();
Object value = gameRule.convertValue(args[offset + 1], t);
if(value == null) {
return CBoolean.FALSE;
}
if(args.length == 2) {
for(MCWorld world : Static.getServer().getWorlds()) {
success = world.setGameRuleValue(gameRule, value);
Expand Down

0 comments on commit 45eddad

Please sign in to comment.